算法第五周解题报告

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值