Two Pointer

链表双指针算法

Two Pointer

141. Linked List Cycle

判断链表是否有环

Can you solve it using O(1) (i.e. constant) memory?
leetcode 141. Linked List Cycle

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

142. Linked List Cycle II

判断链表是否有环,如有找出环的位置
leetcode 142. Linked List Cycle II

假设环的长度为len,让slow pointer 先走len,fast从head开始,slow 和 fast 每次都只走一步,当他们相遇的时候slow走的路程和fast走的路程相同。

class Solution {
    public:
        ListNode * detectCycle(ListNode * head) {

            ListNode * fast ,*slow;
            fast = slow = head;
            while (fast != NULL && fast -> next != NULL) {
                fast = fast -> next -> next;
                slow = slow -> next;
                if (fast == slow)
                    break;
            }

            if (fast == NULL || fast -> next == NULL)
                return NULL;

            slow = slow -> next;
            int len = 1;
            while (slow != fast) {
                len++;
                slow = slow -> next;
            }

            slow = head;
            fast = head;
            while (len) {
                fast = fast -> next;
                len--;
            }

            while (slow != fast) {
                slow = slow -> next;
                fast = fast -> next;
                if (fast -> next == slow)
                    break;
            }

            return slow;

        }
};

876. Middle of the Linked List

寻找链表的中点
fast的速度是slow的2倍,fast到终点时,slow到中点

leetcode

class Solution {
public:
    ListNode* middleNode(ListNode* head) {
        
        ListNode *fast, *slow;
        fast=slow=head;
        while(fast!=NULL && fast->next!=NULL)
        {
            slow=slow->next;
            fast=fast->next->next;
        }
        return slow;
        
    }
};

19. Remove Nth Node From End of List

leetcode

移除倒数第n个元素,关键是找到倒数第n个元素,
使用两个指针,fast 和slow,让fast在slow前面n步,然后俩个一起走,当fast到最后的时候,slow刚好为倒数第n个元素。

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode* dummy=new ListNode(0);
        dummy->next=head;
        ListNode * fast,*slow;
        fast=slow=dummy;
        
        while(n--)
        {
            fast=fast->next;
        }
        while(fast->next!=NULL)
        {
            fast=fast->next;
            slow=slow->next;
        }
        slow->next=slow->next->next;
        
        return dummy->next;
    }
};
代码概述 这是一个关于求解一元二次方程根的编程任务。要求编写一个函数,使用两个指针参数:一个用于传入系数 $ a, b, c $,另一个用于返回计算出的两个根。 代码解析 ```c #include <stdio.h> #include <math.h> void calculateQuadraticRoots(double *coeffs, double *roots) { double a = *(coeffs + 0); // a = coeffs[0] double b = *(coeffs + 1); // b = coeffs[1] double c = *(coeffs + 2); // c = coeffs[2] double discriminant = b * b - 4 * a * c; if (discriminant >= 0) { double sqrtD = sqrt(discriminant); *(roots + 0) = (-b + sqrtD) / (2 * a); // x1 *(roots + 1) = (-b - sqrtD) / (2 * a); // x2 } else { // 复数根无法用实数表示,此处可设为 NaN 或特殊处理 *(roots + 0) = NAN; *(roots + 1) = NAN; } } int main() { double coefficients[3] = {1, -5, 6}; // 示例:x² -5x +6 =0 double roots[2]; calculateQuadraticRoots(coefficients, roots); if (!isnan(roots[0])) { printf("Root 1: %lf\n", roots[0]); printf("Root 2: %lf\n", roots[1]); } else { printf("The equation has complex roots.\n"); } return 0; } ``` - `double *coeffs` 指向包含 $ a, b, c $ 的数组。 - `double *roots` 用于将结果回传给调用函数。 - 使用 `*(ptr + i)` 实现指针偏移访问数据。 - 判别式 $ \Delta = b^2 - 4ac $ 决定根的性质。 知识点(列出该代码中遇到的知识点) 1. **指针参数传递**:通过指针在函数间共享数据,实现“输出参数”。 2. **二次方程求根公式**:根为 $ x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a} $。 3. **判别式与根的性质**:$ \Delta \geq 0 $ 时有实根,否则为复数根。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值