【牛客刷题】链表专项(合并两个链表、链表是否有环、链表中环的入口、删除链表的倒数第n个节点、找第一个公共节点、链表相加Ⅱ)

合并两个链表

https://www.nowcoder.com/share/jump/9321389651694162925269

    ListNode* Merge(ListNode* pHead1, ListNode* pHead2) {
        // write code here
        ListNode* dummy = new ListNode(0);
        ListNode* cur = dummy;
        ListNode* cur1 = pHead1;
        ListNode* cur2 = pHead2;
        while (cur1 != nullptr && cur2 != nullptr) {
            if (cur1->val <= cur2->val) {
                cur->next = cur1;
                cur1 = cur1->next;
            } else {
                cur->next = cur2;
                cur2 = cur2->next;
            }

            cur = cur->next;
        }
        if (cur1 == nullptr && cur2 != nullptr) cur->next = cur2;
        else if (cur2 == nullptr && cur1 != nullptr) cur->next = cur1;
        return dummy->next;
    }

链表是否有环

https://www.nowcoder.com/share/jump/9321389651694163138051

class Solution {
public:
    bool hasCycle(ListNode *head) {
        if (head == nullptr || head->next == nullptr) return false;
        ListNode* fast = head;
        ListNode* slow = head;
        while (fast != nullptr && fast->next != nullptr) {
            fast = fast->next->next;
            slow = slow->next;
            if (fast == slow) return true;
        }
        return false;
    }
};

链表中环的入口

https://www.nowcoder.com/share/jump/9321389651694163164627
第一次因为想少写几步代码,所以直接return hasCycle ? index1 : null;忘了增加判断有环再进行while循环找环入口了,所以导致报错。看来还是逻辑最重要,不能一味图方便:

    ListNode* EntryNodeOfLoop(ListNode* pHead) {
        if (pHead == nullptr || pHead->next == nullptr) return nullptr;
        ListNode* fast = pHead;
        ListNode* slow = pHead;
        ListNode* index1 = pHead;
        ListNode* index2;  
        bool hasCycle = false;
        while(fast != nullptr && fast->next != nullptr) {
            fast = fast->next->next;
            slow = slow->next;
            if (slow == fast) {
                index2 = slow;
                hasCycle = true;
                break;
            }
        }
        if (hasCycle) {
            while (index1 != index2) {
                index1 = index1->next;
                index2 = index2->next;
            }
            return index1;
        }
        return nullptr;
    }

删除链表的倒数第n个节点

https://www.nowcoder.com/share/jump/9321389651694164822005
思路,先反转,然后从头删除第n个,再翻转回来

    ListNode* reverseList(ListNode* head) {
        ListNode* prev = nullptr;
        ListNode* cur = head;
        while (cur != nullptr) {
            ListNode* temp = cur->next;
            cur->next = prev;
            prev = cur;
            cur = temp;
        }
        return prev;
    }

    ListNode* removeNthFromEnd(ListNode* head, int n) {
        // write code here
        ListNode* reverseHead = reverseList(head);
        ListNode* dummy = new ListNode(0);
        dummy->next = reverseHead;
        ListNode* cur = reverseHead;
        ListNode* pre = dummy;
        while (--n) {
            cur = cur->next;
            pre = pre->next;
        }
        pre->next = cur->next;
        return reverseList(dummy->next);
    }

找第一个公共节点

https://www.nowcoder.com/share/jump/9321389651694165945874

    ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
        int len1 = 0, len2 = 0;
		ListNode* cur1 = pHead1;
		ListNode* cur2 = pHead2;
		while (cur1 != nullptr) {
			len1++;
			cur1 = cur1->next;
		}
		while (cur2 != nullptr) {
			len2++;
			cur2 = cur2->next;
		}
		if (len1 > len2) {
			swap(len1, len2);
			swap(pHead1, pHead2);
		}
		int n = len2 - len1;
		cur1 = pHead1;
		cur2 =  pHead2;
		while (n--) {
			cur2 = cur2->next;
		}
		while (cur1 != nullptr) {
			if (cur1 == cur2) return cur1;
			else {
				cur1 = cur1->next;
				cur2 = cur2->next;
			}
		}
		return nullptr;
    }

链表相加Ⅱ

还是喜欢用翻转来做:

    ListNode* reverse(ListNode* head) {
        ListNode* pre = nullptr;
        ListNode* cur = head;
        while (cur != nullptr) {
            ListNode* temp = cur->next;
            cur->next = pre;
            pre = cur;
            cur = temp;
        }
        return pre;
    }

    ListNode* addInList(ListNode* head1, ListNode* head2) {
        head1 = reverse(head1);
        head2 = reverse(head2);
        ListNode* cur1 = head1;
        ListNode* cur2 = head2;
        ListNode* dummy = new ListNode(0);
        ListNode* cur = dummy;
        int index = 0, sum = 0;

        while (cur1 != nullptr || cur2 != nullptr) {
            int val1 = (cur1 != nullptr) ? cur1->val : 0;
            int val2 = (cur2 != nullptr) ? cur2->val : 0;

            sum = val1 + val2 + index;
            cur->next = new ListNode(sum % 10);
            index = sum / 10;

            if (cur1) cur1 = cur1->next;
            if (cur2) cur2 = cur2->next;
            cur = cur->next;
        }

        if (index) cur->next = new ListNode(index);

        return reverse(dummy->next);
    }

你可能感兴趣的:(链表,数据结构)