Data structure-linked list exercises (partial)

How to determine whether a linked list has a ring

Excerpt 141. Circular Linked List
Insert picture description here

Given a linked list, determine whether there is a ring in the linked list. If there is a node in the linked list, it can be reached again by continuously tracking the next pointer, then there is a ring in the linked list. In order to represent the rings in a given linked list, we use the integer pos to indicate the position where the end of the linked list is connected to the linked list (the index starts from 0). If pos is -1, then there is no ring in the linked list. Note: pos is not passed as a parameter, just to identify the actual situation of the linked list. If there is a ring in the linked list, return true. Otherwise, it returns false.

Method 1: Hash table cache

A unordered_setrecording visited nodes to <ListNode*as element type, and then traversing the linked list by again hash table O (1) to lookup efficiency. Time complexity O(n), space complexityO(n)

class Solution {
    
    
public:
	bool hasCycle(ListNode* head) {
    
    
		//基本思想:哈希表,时间复杂度O(n)空间复杂度O(n)
		unordered_set<ListNode*> setNode;
		while (head != NULL)
		{
    
    
			if (setNode.find(head) == setNode.end())
				setNode.insert(head);
			else
				return true;
			head = head->next;
		}
		return false;
	}
};

Method two: fast and slow pointer

Regarding the linked list forming a ring as a runway, (遍历速率)two pointers with different moving speeds will meet after traversing several times. At this time, it is enough to judge whether the corresponding node of the pointer points to the same address. Time complexity O(n)and space complexity degreeO(1)

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(slow == fast){
    
    
                return true;
            }
        }
        return false;
    }
};

How to judge whether two singly linked lists intersect, and the intersection point

Insert picture description here

Method 1: Compare elements on the same starting line

For real interview questions, take the longest linked list, traverse first abs(lenA - lenB), then traverse and compare

class Solution {
    
    
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
    
    
        int lenA = 0, lenB = 0;
        ListNode* nodeA = headA, *nodeB = headB;
        while(nodeA){
    
    
            ++lenA;
            nodeA = nodeA->next;
        }
        while(nodeB){
    
    
            ++lenB;
            nodeB = nodeB->next;
        }
        if(lenA >= lenB){
    
    
            int dif = lenA - lenB;
            while(dif--)	headA = headA->next;
        }
        else{
    
    
            int dif = lenB - lenA;
            while(dif--)	headB = headB->next;
        }
        while(headA && headB){
    
    
            if(headA == headB)	return headA;
            headA = headA->next;
            headB = headB->next;
        }
        return nullptr;
    }
};

Guess you like

Origin blog.csdn.net/lr_shadow/article/details/113791964