算法第五周解题报告

来源:互联网 发布:手机延时软件 编辑:程序博客网 时间:2024/05/13 04:50

21. Merge Two Sorted Lists

问题描述:Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists.

解题思路:简单题,设置两个指针再链表上移动,每次将链表顶端的较小的元素取出接到新链表上即可。

代码如下:

class Solution {public:    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {        ListNode *res(NULL);        ListNode *cur(NULL);        ListNode* l1Cur(l1), *l2Cur(l2);        res = new ListNode(-1);        cur = res;        while (l1Cur != NULL && l2Cur != NULL){            ListNode *tmp = new ListNode(-1);            tmp -> next = NULL;            tmp -> val = (l1Cur -> val < l2Cur -> val ? l1Cur -> val : l2Cur -> val);            ListNode *s1 = l1Cur;            l1Cur = (l1Cur -> val < l2Cur -> val ? l1Cur -> next : l1Cur);            l2Cur = (s1 -> val < l2Cur -> val ? l2Cur : l2Cur -> next);            cur -> next = tmp;            cur = cur -> next;        }        if(l1Cur != NULL){            cur -> next = l1Cur;        }        if(l2Cur != NULL){            cur -> next = l2Cur;        }        res = res -> next;        return res;    }};
结果如下:



23. Merge k Sorted Lists

题目描述:Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.

解题思路:解题思路同上题,只是一个简单的扩展而已。一个小技巧是当一个链表遍历完了就将它移除向量。

代码如下:

class Solution {public:    ListNode* mergeKLists(vector<ListNode*>& lists) {        for(int i = 0; i < lists.size(); ++i){            if(lists[i] == NULL){                int j = lists.size() - 1;                while(lists[j] == NULL && j > i){                    lists.pop_back();                    --j;                }                if (lists[j] == NULL){                    lists.pop_back();                } else{                    lists[i] = lists[j];                    lists.pop_back();                }            }        }        if(lists.size() == 0) return NULL;                ListNode *res = new ListNode(-1);        ListNode *curP = res;        while (lists.size() != 1){            ListNode *tmp = NULL;            int index = -1;            int min = 0;            for(int i = 0; i < lists.size(); ++i){                if(index == -1 || min > lists[i] -> val){                    min = lists[i] -> val;                    index = i;                }            }            tmp = new ListNode(-1);            tmp -> val = lists[index] -> val;            curP -> next = tmp;            curP = curP -> next;            lists[index] = lists[index] -> next;            if(lists[index] == NULL){                lists[index] = lists[lists.size() - 1];                lists.pop_back();            }        }        curP -> next = lists[0];        return res -> next;    }};
结果如下:



24. Swap Nodes in Pairs

题目描述:

Given a linked list, swap every two adjacent nodes and return its head.

For example,
Given 1->2->3->4, you should return the list as 2->1->4->3.

Your algorithm should use only constant space. You may not modify the values in the list, only nodes itself can be changed.

解题思路:

设置前后两个相邻指针即可,需要注意的是指针是否已经达到了链表尾

代码如下:

class Solution {public:    ListNode* swapPairs(ListNode* head) {        ListNode *pre(NULL), *back(NULL), *left(head), *right(NULL);        if(left != NULL) right = left -> next;        while(left != NULL && right != NULL){            ListNode *preLNext(left -> next), * preRNext(right -> next);            right -> next = left;            left -> next = preRNext;            if(pre != NULL){                pre -> next = right;            } else {                head = right;            }            //move forward            pre = left;            left = left -> next;            if(left != NULL){                right = left -> next;            }        }        return head;    }};
结果如下:



138. Copy List with Random Pointer

题目描述:

A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null.

Return a deep copy of the list.

解题思路:这一题是真正比较需要技巧的题目。

本人使用的技巧是:假设被复制的链表为L1, 生成的链表为L2。

将L1的每个节点的地址记录在数组当中;

将L1每个节点的next指向res中对应的节点,构成一个一一对应关系。

对于res中的每个节点,res -> randomP = L1 -> randomP -> next

最后根据数组将L1复原。


代码如下:

class Solution {public:    RandomListNode *copyRandomList(RandomListNode *head) {        if(head == NULL) return NULL;        vector<RandomListNode*> precord;        RandomListNode *res(NULL), *recordH(head), *recordR;        res = new RandomListNode(-1);        recordR = res;        while(recordH != NULL){            precord.push_back(recordH);            RandomListNode *tmp = new RandomListNode(-1), *tmp1 = recordH;            tmp -> label = recordH -> label;            tmp -> random = recordH -> random;            recordH = recordH -> next;            recordR -> next = tmp;            recordR = recordR -> next;            tmp1 -> next = recordR;        }        recordR = res -> next;        while(recordR != NULL){            if(recordR -> random != NULL)                recordR -> random = recordR -> random -> next;            recordR = recordR -> next;        }        for(int i = 0; i < precord.size() - 1; ++i){            precord[i] -> next = precord[i + 1];        }        precord[precord.size() -1] -> next = NULL;        return res -> next;    }};

结果如下:


0 0