数据结构-链表习题(部分)

如何判断链表有环

节选141.环形链表
在这里插入图片描述

给定一个链表,判断链表中是否有环。 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。 如果链表中存在环,则返回 true 。 否则,返回 false 。

方法一:哈希表缓存

unordered_set记录访问过的结点,以<ListNode*作为元素类型,遍历一遍链表再通过哈希表O(1)的查找效率即可。时间复杂度O(n),空间复杂度O(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;
	}
};

方法二:快慢指针

把形成环的链表看成是一个跑道,移动速率(遍历速率)不同的两个指针,再遍历若干次后会相遇,此时再判断指针对应的结点是否指向相同的地址即可,时间复杂度O(n),空间复杂度O(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;
    }
};

如何判断两个单链表是否相交,以及相交点

在这里插入图片描述

方法一:同一起跑线对比元素

真实的面试题目,取最长的链表,先遍历abs(lenA - lenB),再遍历比对即可

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;
    }
};

猜你喜欢

转载自blog.csdn.net/lr_shadow/article/details/113791964