双指针法解题记录

本文详细介绍了LeetCode中涉及链表的五道经典题目,包括环形链表的检测、找到环的入口节点、判断两个链表是否相交、寻找链表中倒数第k个节点以及移除链表元素的方法。通过快慢指针等技巧,解析了这些链表问题的解决方案。
摘要由CSDN通过智能技术生成

目录

Leetcode.141-环形链表

Leetcode.142-环形链表Ⅱ

Leetcode.160-相交链表

Leetcode.剑指offer22-链表中倒数第k个节点

Leetcode.27-移除元素


Leetcode.141-环形链表

题目要求判断一个链表中是否有环

这题采用快慢指针解答,构造fast指针与slow指针,slow指针每次前进一个节点,fast指针每次前进两个节点。fast指针走到NULL则说明链表中无环,两个指针相遇说明有环。

注意对head以及head->next判空,以及fast指针的判空

代码部分:

bool hasCycle(struct ListNode *head) {
    if (head == NULL || head->next == NULL) {
		return false;
	}
	struct ListNode* fast = head->next;
	struct ListNode* slow = head;
	while (fast != slow) {
        if (fast == NULL || fast->next == NULL) {
			return false;
		}
		fast = fast->next->next;
		slow = slow->next;
	}
	return true;
}

Leetcode.142-环形链表Ⅱ

题目要求判断一个链表中是否有环,若有环找出链表入环的结点

这题仍使用快慢指针解答,但需要画图找计算规律。判断是否有环与上题一致

 如图路程D = 路程S2,所以在两个指针相遇后,另设指针从头结点开始走,slow指针从相遇点往前走,两指针相遇位置即入环结点。

代码部分:

struct ListNode *detectCycle(struct ListNode *head) {
    if (head->next == NULL || head->next->next == NULL) {
		return NULL;
	}
	struct ListNode* slow = head;
	struct ListNode* fast = head;
	while (slow != fast) {
        if (fast == NULL || fast->next == NULL) {
			return NULL;
		}
		fast = fast->next->next;
		slow = slow->next;
	}
	struct ListNode* ptr = head;
	while (ptr != slow) {
		ptr = ptr->next;
		slow = slow->next;
	}
	return slow;
}

Leetcode.160-相交链表

题目要求判断两个链表是否相交,并返回相交处的节点

这题使用双指针法,本质类似快慢指针,a指针走完a链后换到b链走,b指针走完b链换到a链走......如此循环两个指针若在同一个结点相遇则两个链表相交,若两个指针同时走到NULL则说明两条链表不相交

代码部分:

struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    if (headA == NULL || headB == NULL) {
        return NULL;
    }
    struct ListNode *pA = headA, *pB = headB;
    while (pA != pB) {
        pA = pA == NULL ? headB : pA->next;//先判断pA是否是空:不是的话pA = pA->NEXT,是的话pA = headB。
        pB = pB == NULL ? headA : pB->next;//运算符优先级  ==  >  ?: >  =
    }
    return pA;
}

Leetcode.剑指offer22-链表中倒数第k个节点

题目要求返回链表倒数第k个节点

这题使用双指针法,先让快指针先走k步,快慢指针再一起走即可实现快指针到NULL时,慢指针所在位置是链表中倒数第k个结点。

代码部分:

struct ListNode* getKthFromEnd(struct ListNode* head, int k){
    struct ListNode *fast = head, *slow = head;
    while((k--) > 0){
        fast = fast->next;
    }
    while(fast != NULL){
        fast = fast->next;
        slow = slow->next;
    }
    return slow;
}

Leetcode.27-移除元素

题目给一个数组,要求原地移除所有数值等于 val 的元素,并返回移除后数组的新长度。

定义一个快指针fast一个慢指针slow,当slow <= fast时执行循环,如果nums[fast]的值等于val那就fast减一,如果nums[slow]的值不等于val那就slow加一,当nums[fast] != val 且 nums[slow] == val时将nums[fast]的值赋给nums[slow],且让slow加一,fast减一,出循环后返回新数组的长度slow即可。

代码部分:

int removeElement(int* nums, int numsSize, int val){
    if (nums == NULL || numsSize == 0)
    return 0; 
    int slow = 0,fast = numsSize - 1;
    while (slow <= fast) {
        if (nums[fast] == val) {
            --fast;
            continue;
        }
        if (nums[slow] != val) {
            ++slow;
            continue;
        }
        nums[slow] = nums[fast];
        ++slow;
        --fast;
    }
    return slow;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值