《慕课网玩转算法面试》笔记及习题解答5.4.~5.6

来源:互联网 发布:淘宝售后客服术语大全 编辑:程序博客网 时间:2024/06/05 02:59

LeetCode 24. Swap Nodes in Pairs 

思路:多用几个指针,和头插法差不多,只是要移动pre节点         

class Solution {public:    ListNode* swapPairs(ListNode* head) {        ListNode* dummyHead = new ListNode(-1);        dummyHead->next = head;        ListNode* pre = dummyHead;        while(pre->next && pre->next->next){            ListNode* first = pre->next;            ListNode* second = first->next;            ListNode* succ = second->next;            pre->next = second;            second->next = first;            first->next = succ;            pre = pre->next->next;        }        ListNode* resNode = dummyHead->next;        delete dummyHead;        return resNode;    }};

 

LeetCode 25. Reverse Nodes in k-Group    

思路:这题其实也是头插法的变形,先求总长度确保需要逆序,在( pre, pre+k+1 ]内先找到cur = pre+1然后循环遍历到cur = pre+k将cur->next 插到区间的头部,遍历完之后将pre节点设置到 pre+k即当前的cur节点所在的位置。将长度num -= k判断后续长度是否需要继续逆序。

    ListNode* reverseKGroup(ListNode* head, int k) {        if(k <= 1)            return head;
//老规矩,链表问题先设一个虚拟头节点        ListNode* dummyHead = new ListNode(-1);        dummyHead->next = head;        ListNode* pre = dummyHead;        ListNode* cur = dummyHead;                int num = 0;
//求长度        while(cur->next){            cur = cur->next;            num++;        }                    cout << num << endl;        while(num >= k){            cur = pre->next;//注意,此时应该是需要逆序区间(pre,pre+k+1]的pre+1节点,此节点不需要逆序            for(int i = 1; i <= k-1;i++){//遍历,头插                ListNode* next = cur->next;                cur->next = next->next;                next->next = pre->next;                pre->next = next;            }            pre = cur;            num -= k;                   }        ListNode* resNode = dummyHead->next;        delete dummyHead;        return resNode;    }


LeetCode 147. Insertion Sort List  

    ListNode* insertionSortList(ListNode* head) {        ListNode* dummyHead = new ListNode(-1);        dummyHead->next = head;        ListNode* cur = head;        while(cur && cur->next){            //每次将cur->next插入到之前的节点            int val = cur->next->val;            ListNode *preNode = dummyHead;            //在当前node的前面寻找比当前node的val更大的节点            while(preNode != cur->next && preNode->next->val < val){                preNode = preNode->next;            }            //如果preNode == cur说明之前没有比当前node的val更大的节点,不需要插入,直接向后移动            if(preNode == cur)                cur = cur->next;            //找到了比当前node的val更大的节点,插入            else{                ListNode* moveNode = cur->next;                cur->next = moveNode->next;                moveNode->next = preNode->next;                preNode->next = moveNode;            }        }        ListNode* resNode = dummyHead->next;        delete dummyHead;        return resNode;            }



LeetCode 148. Sort List 

归并排序,一直有bug。。之后再说吧       

双指针问题

LeetCode 19. Remove Nth Node From End of List  

    ListNode* removeNthFromEnd(ListNode* head, int n) {        ListNode* dummyHead = new ListNode(-1);        dummyHead->next = head;        ListNode* fast = dummyHead;               ListNode* slow = dummyHead;        //fast先向前移动n位        while(n-- && fast->next) fast = fast->next;        if(n > 0) return head;        while(fast->next){            slow = slow->next;            fast = fast->next;        }        //此时的slow指针就是倒数第n个节点        ListNode* moveNode = slow->next;        slow->next = moveNode->next;        delete moveNode;        ListNode* resNode = dummyHead->next;        delete dummyHead;        return resNode;            }


LeetCode 61

    ListNode* rotateRight(ListNode* head, int k) {        if(k <= 0 || !head)            return head;        ListNode* dummyHead = new ListNode(-1);        dummyHead->next = head;        ListNode* p = dummyHead;        int len = 0;        //计算链表长度        while(p->next){            p = p->next;            len++;        }        //每旋转len次就变回原形,因此可以直接取余        if( k >= len) k %= len;        int steps = len - k;        p = dummyHead;        while(steps-- > 0)            p = p->next;        ListNode* cur = dummyHead;        //用头插法逐个插入,注意此时的头是移动的        for(int i = 0; i < k; i++)        {            ListNode* moveNode = p->next;            p->next = moveNode->next;            moveNode->next = cur->next;            cur->next = moveNode;            cur = cur->next;        }        ListNode* resNode = dummyHead->next;        delete dummyHead;        return resNode;    }


LeetCode 143

    void reorderList(ListNode* head) {        if(head == NULL || head->next == NULL || head->next->next == NULL)            return;        ListNode* fast = head;        ListNode* slow = head;        //快慢指针找到中间节点        while(fast->next && fast->next->next){            fast = fast->next->next;            slow = slow->next;        }        ListNode* p = slow->next;        //对后部分链表翻转        while(p->next){            ListNode* moveNode = p->next;            p->next = moveNode->next;            moveNode->next = slow->next;            slow->next = moveNode;        }        ListNode* pre1 = head;        ListNode* pre2 = new ListNode(-1);        pre2->next = slow->next;        slow->next = NULL;        //将后部分链表插入前部分链表中        while(pre2->next)        {            ListNode* moveNode = pre2->next;            pre2->next = moveNode->next;            moveNode->next = pre1->next;            pre1->next = moveNode;            pre1 = pre1->next->next;        }        delete pre2;            }


LeetCode 234

    bool isPalindrome(ListNode* head) {        if(!head || !head->next)            return true;        ListNode* fast = head;        ListNode* slow = head;        while(fast->next && fast->next->next ){            fast = fast->next->next;            slow = slow->next;        }        ListNode* p = slow->next;        //翻转后半部分链表        while(p->next){            ListNode* moveNode = p->next;            p->next = moveNode->next;            moveNode->next = slow->next;            slow->next = moveNode;        }        ListNode* tail = slow->next;        //将后半部分链表分开        slow->next = NULL;        //比较两个链表是否相同        while(head && tail){            if(head->val != tail->val)                return false;            else{                head = head->next;                tail = tail->next;            }        }        return true;    }


阅读全文
0 0