鏈表題目整理(leetcode)

1 鏈表逆序 206

遍歷一個鏈表,建立一個新的鏈表節點,每次都往新的鏈表的頭部插入, 就實現了逆序

class Solution {
public:
    ListNode* ReverseList(ListNode* pHead) {
        ListNode *temp;
        ListNode *ret = 0;
        while(pHead){
            temp = pHead->next;
            pHead -> next = ret;
            ret = pHead;
            pHead = temp;
        }
        return ret;
    }
};

2 將鏈表在位置m到n逆序 92

上一題的擴展,主要是想好 把三段給連起來,存一下相應的節點

class Solution {
public:
    ListNode* reverseBetween(ListNode* head, int m, int n) {
        ListNode *ret = 0;
        ListNode *s = head; //存儲一下開始指針
        ListNode *pre_head = head;
        ListNode *modify_tail = 0;
        int i = 1;
        while(head!=NULL){
            if(i>=m && i <= n){
                if(i == m){
                    modify_tail = head;
                }
                ListNode *temp = head->next;
                head -> next = ret;
                ret = head;
                head = temp;
            }else if(i < m){
                pre_head = head;
                head = head -> next;
            }else{
                break;
            }
            i++;
        }
        if(m == 1){ //當m從第一個開始逆序時,單獨處理,不能返回s了,需要返回ret
            modify_tail->next = head;
            return ret;
        }
        pre_head->next = ret;
        modify_tail->next = head;
        return s;
    }
};

3 求兩個鏈表的結點 160

主要是求兩個鏈表的長度,將鏈表對齊, 然後依次往後判斷節點是否相同

class Solution(object):
    def getIntersectionNode(self, headA, headB):
        """
        :type head1, head1: ListNode
        :rtype: ListNode
        """
        lenA = self.get_len(headA)
        lenB = self.get_len(headB)
        if lenA > lenB:
            for i in range(lenA - lenB):
                headA = headA.next
        if lenB > lenA:
            for i in range(lenB - lenA):
                headB = headB.next
        while headA and headB:
            if headA == headB:
                return headA
            headA = headA.next
            headB = headB.next
        return None
    
    def get_len(self, head):
        counter = 0
        while head:
            counter += 1
            head = head.next
        return counter

4 鏈表求環 ,相交節點   141  142

設置兩個指針,fast slow  fast每次走兩步,slow每次一步,如果fast走到頭了,還沒有相遇則沒有交點

如果相遇,記錄此時的結點爲meet, meet到環入口節點距離==head到入口節點距離

class Solution(object):
    def hasCycle(self, head):
        """
        :type head: ListNode
        :rtype: bool
        """
        fast = slow = head
        while fast and fast.next:
            fast = fast.next.next
            slow = slow.next
            if fast == slow:
                return True
        return False
class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        ListNode *s = head;
        ListNode *fast = head;
        ListNode *slow = head;
        ListNode *meet = 0;
        while(fast){
            fast = fast->next;
            slow = slow -> next;
            if(fast == NULL){
                return NULL;
            }
            fast = fast->next;
            if(fast == slow){
                meet = slow;
                break;
            }
        }
        if(!meet){
            return NULL;
        }
        while(slow != s){
            slow = slow -> next;
            s = s->next;
        }
        return s;
    }
};

5 分割鏈表 86

題目:將小於某數的節點放到前面, 大於的放到後面

建立兩個鏈表節點,遍歷一次,小的往前面的鏈表加,大的往另一個鏈表上加 ,然後合併一下

class Solution {
public:
    ListNode* partition(ListNode* head, int x) {
        ListNode bigger_head(0);
        ListNode less_head(0);
        ListNode *bigger = &bigger_head;
        ListNode *less = &less_head;
        ListNode *ret = less;
        while(head!= NULL){
            if(head->val >= x){
                bigger -> next = head;
                bigger = bigger -> next;
            }else{
                less -> next = head;
                less = less -> next;
            }
            head = head -> next;
        }
        less -> next = bigger_head.next;
        bigger -> next = NULL; // 必須手動指向空 不然一直超時
        return ret->next;
    }
};

6 複製還隨機指針的鏈表,深度拷貝 138 

就是比普通的鏈表多一個random指針,隨機指

題目解讀:指針裏面存的是地址,深度拷貝的話,會產生新的地址的,不能用之前的地址指針了,必須建立一個映射保存一下原鏈表地址->節點位置的映射, 和 節點位置->新鏈表地址的映射 ,從而使兩個鏈表相關聯

class Solution {
public:
    RandomListNode *copyRandomList(RandomListNode *head) {
        map<RandomListNode *, int> node_int; //原鏈表地址->位置映射
        vector<RandomListNode *> int_node;//位置->新鏈表地址映射  用vector就行
        RandomListNode *p = head;
        int i = 0;
        while(p){
            int_node.push_back(new RandomListNode(p->label));//保存兩個映射
            node_int[p] = i;
            p = p ->next;
            i ++;
        }
        int_node.push_back(0);
        i = 0;
        p = head;
        while(p){
            int_node[i]->next = int_node[i+1];  //next填充上
            if(p->random){ // 因爲空的沒有對應序號  必須判斷
                int_node[i]->random = int_node[node_int[p->random]];//randonm填充
            }
            p = p -> next;
            i++;
        }
        return int_node[0];
    }
};

7 排序鏈表的合併 21

建立一個新的鏈表,遍歷比較即可,不管那個長,把剩下的加到後面

class Solution:
    def mergeTwoLists(self, l1, l2):
        """
        :type l1: ListNode
        :type l2: ListNode
        :rtype: ListNode
        """
        ret = ListNode(0)
        c = ret
        while l1 != None and l2 != None:
            if l1.val > l2.val:
                ret.next = l2
                l2 = l2.next
            else:
                ret.next = l1
                l1 = l1.next
            ret = ret.next
        while l1 is not None:
            ret.next = l1
            ret = ret.next
            l1 = l1.next
        while l2 is not None:
            ret.next = l2
            l2 = l2.next
            ret = ret.next
        return c.next

8 合併K個有序鏈表 23

思路1:

拿到所有值到  list中  sort後,再連接起來 k鏈表n節點 複雜度 O(kn*log(kn))

思路2:

暴力合併, 前兩個合併後再和第三個合併 再繼續往下 k鏈表需要k-1次  n+2n+3n+(k-1)*n  

思路3:

歸併後合併 比如4個,前兩個先合併,後兩個合併,再合併一次 n*(k/2) + 2*n *(k/4) + ... + 2^log(k) * n  /  2 ^ log(k)  = 1/2(kn*log(k))

思路3代碼

class Solution:
    def mergeKLists(self, lists):
        """
        :type lists: List[ListNode]
        :rtype: ListNode
        """
        if len(lists) == 0:
            return
        if len(lists) == 1:
            return lists[0]
        if len(lists) == 2:
            return self.mergeTwoLists(lists[0], lists[1])
        mid = len(lists) // 2
        sublist1 = lists[:mid]
        sublist2 = lists[mid:]
        node1 = self.mergeKLists(sublist1)
        node2 = self.mergeKLists(sublist2)
        return self.mergeTwoLists(node1, node2)
    
    def mergeTwoLists(self, l1, l2):
        """
        :type l1: ListNode
        :type l2: ListNode
        :rtype: ListNode
        """
        ret = ListNode(0)
        c = ret
        while l1 != None and l2 != None:
            if l1.val > l2.val:
                ret.next = l2
                l2 = l2.next
            else:
                ret.next = l1
                l1 = l1.next
            ret = ret.next
        while l1 is not None:
            ret.next = l1
            ret = ret.next
            l1 = l1.next
        while l2 is not None:
            ret.next = l2
            l2 = l2.next
            ret = ret.next
        return c.next

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章