双指针算法

对撞指针

 

给定一个有序整型数组和一个整数target,在其中寻找两个元素,十其和为target,返回这两个数的索引

如:[2,7,11,15],target=9

输出 [1,2]

 

最直接的解法就是暴力解法,双层遍历,这样他的时间复杂度就是O(n^2)

但是暴力解法没有利用他的已知条件,就是有序

 

双指针指定数组左右两个下标,通过将两个下标向中间移动来求出解 Arr[i]+Arr[j]==target

 

代码

#include<iostream>

using namespace std;


pair<int, int> DoublePointer(int* Arr, int ArrLen,int Target);

int main(void)
{
    int ArrLen;
    cin >> ArrLen;
    int* Arr = new int[ArrLen];

    for (int i = 0; i < ArrLen; ++i)
        cin >> Arr[i];
    int Target;
    cin >> Target;

    pair<int,int> Rslt=DoublePointer(Arr, ArrLen, Target);

    cout << Rslt.first << " " << Rslt.second << endl;

    system("pause");
    return 0;
}

pair<int, int> DoublePointer(int* Arr, int ArrLen,int Target)
{
    int L = 0;
    int R = ArrLen - 1;
    while (L < R)
    {
        if ((Arr[L] + Arr[R]) == Target)
            return pair<int, int>(L+1, R+1);
        if ((Arr[L] + Arr[R]) < Target)
            ++L;
        if ((Arr[L] + Arr[R]) > Target)
            --R;
    }
    return pair<int,int>(-1,-1);
}

 

其他的指针对撞问题

leetcode125

给定一个字符串,只看其中的数字和字母,忽略大小写,判断这个字符串是否为回文串

 

leetcode344

给定一个字符串,返回这个字符串的倒序字符串(限制时间复杂度)

ij一个头一个尾,然后交换ij位置即可

 

leetcode345

给定一个字符串,将该字符串中的元音字母反转

 

快慢指针

 

给定一个链表,返回链表开始入环的第一个节点,如果链表无环,则返回null

为了表示给定链表中的环,使用整数pos来表示链表尾连接到链表中的位置,索引从0开始,如果pos是-1则表示链表中没有环

 

暴力算法:将链表的所有点都放到一个集合中,走到环时循环出现的第一个数字在集合中定位即可,但是如果显示时间复杂度为O(n),那么暴力解法行不通

 

快慢指针:跑的快的人会给跑得慢的人套圈,快指针一次走两个节点,慢指针一次只走一个节点,他们最终会在环的某个位置相遇

 

如果链表没有环,那么快指针走到链表末尾直接返回NULL

如果快慢指针相遇,此时再加一个慢指针,两个慢指针一个从链表首个节点出发,另一个从快慢指针相遇的位置出发,这两个慢指针再次相遇的地方就是环的入口

 

伪代码

LinkList FastSlowPointer(LinkList &HeadNode)
{
    LinkList FastPointer, SlowPointer;
    FastPointer = HeadNode;
    SlowPointer = HeadNode;
    while (FastPointer != NULL)
    {
        // 先走一步
        FastPointer = FastPointer.Next;
        if (FastPointer == NULL)
            return NULL;

        // 快慢都走一步
        FastPointer = FastPointer.Next;
        SlowPointer = SlowPointer.Next;

        if (SlowPointer == FastPointer)
            break;

    }

    if (FastPointer == NULL)
        return NULL;

    LinkList p1 = SlowPointer;
    LinkList p2 = HeadNode;
    while (p1 != p2)
    {
        p1 = p1.Next;
        p2 = p2.Next;
    }
    return p1;
}

 

posted @ 2020-10-21 22:56  Wangtn  阅读(150)  评论(0编辑  收藏  举报