传统弱校HFUT的蒟蒻,真相只有一个

算法复习:双指针(对撞指针、快慢指针)

一、快慢指针: leedcode 142. 环形链表 II

快慢指针的思想是设置慢指针slow和快指针fast,slow每次走一步,fast每次走两步,如果有环fast指针和slow指针必然相遇,相遇时

定义新的指针p从head开始和slow从当前位置起每次都走一步,直到相遇,相遇的位置就是环的入口。

class Solution {
public:
    ListNode *detectCycle(ListNode *head)
    {
        int lable=0;
        struct ListNode *slow,*fast,*pp;
        if(head==NULL)
            return NULL;
        if(head->next==NULL)
            return NULL;
        slow=head->next;
        if(slow->next==NULL)
            return NULL;
        fast=slow->next;
        while(slow!=fast)// 步骤一:使用快慢指针判断链表是否有环
        {
            if(fast->next==NULL)
            {
                lable=1;
                break;
            }
            fast=fast->next;//快指针走两步
            if(fast->next==NULL)
            {
                lable=1;
                break;
            }
            fast=fast->next;
            slow=slow->next;//慢指针走一步
        }
        if(lable==1)
            return NULL;
        pp=head;
        while(pp!=slow)// 步骤二:若有环,找到入环开始的节点
        {
            pp=pp->next;
            slow=slow->next;
        }
        return pp;
    }
};
leedcode 142
int main()
{
    struct ListNode *head,*p,*q;
    head=NULL;
    q=(ListNode*)malloc(sizeof(ListNode));//malloc的方法
    q->next=NULL;
    int num;
    cout<<"Input num"<<endl;
    scanf("%d",&num);
    for(int i=0;i<num;i++)//建链表插入链表
    {
        p=(ListNode*)malloc(sizeof(ListNode));
        cout<<"Input number"<<endl;
        p->next=NULL;
        scanf("%d",&p->val);
        if(i==0)
            head=p;
        else
            q->next=p;
        q=p;
    }
    int loop;
    cout<<"Input loop"<<endl;
    scanf("%d",&loop);
    if(loop==-1)
        q->next=NULL;
    else//建循环链表
    {
        p=(ListNode*)malloc(sizeof(ListNode));
        p=head;
        for(int i=0;i<loop;i++)
        {
            p=p->next;
        }
        q->next=p;
    }
    p=detectCycle(head);
    cout<<p->val<<endl;
    return 0;
}
main函数

 

二、对撞指针:leedcode 11. 盛最多水的容器

对撞指针要求两个指针up和down分别从前后两端向中间走,指定一个指针更新规则

本题计算面积,水的上限由短板决定,因此更新规则是选取短的那一个边的方向向中间移动,直到指针碰撞

int min(int a,int b)
    {
        if(a>b)
            return b;
        else
            return a;
    }
    int maxArea(vector<int>& height)
    {
        int up=0,down=height.size()-1;
        int area=down*min(height[0],height[down]),tmp_area=0;
        while(up<down)
        {
            tmp_area=(down-up)*min(height[up],height[down]);
            if(tmp_area>area)
                area=tmp_area;
            if(height[up]>height[down])
                down--;
            else
                up++;
        }
        return area;
    }
leedcode 11

leedcode 125. 验证回文串

双指针根据规则向中间靠拢即可

class Solution {
public:
    bool isPalindrome(string s) {
        int up=0,down=s.size()-1;
        int lable=0;
        while(up<=down)
        {
            if((s[up]>='0'&&s[up]<='9')||(s[up]>='A'&&s[up]<='Z')||(s[up]>='a'&&s[up]<='z'))
            {
                if(s[up]>='A'&&s[up]<='Z')
                    s[up]=s[up]+('a'-'A');
            }
            else
            {
                up++;
                continue;
            }
            if((s[down]>='0'&&s[down]<='9')||(s[down]>='A'&&s[down]<='Z')||(s[down]>='a'&&s[down]<='z'))
            {
                if(s[down]>='A'&&s[down]<='Z')
                    s[down]=s[down]+('a'-'A');
            }
            else
            {
                down--;
                continue;
            }
            if(s[up]==s[down])
            {
                up++;
                down--;
            }
            else
            {
                lable=1;
                break;
            }
        }
        if(lable==1)
            return false;
        else
            return true;
    }
};
leedcode 125

 leedcode 167. 两数之和 II - 输入有序数组

class Solution {
public:
    vector<int> twoSum(vector<int>& numbers, int target) {
        int up=0,down=numbers.size()-1;
        while(up<=down)
        {
            if(numbers[up]+numbers[down]>target)
            {
                down--;
                continue;
            }
            if(numbers[up]+numbers[down]<target)
            {
                up++;
                continue;
            }
            if(numbers[up]+numbers[down]==target)
                break;
        }
        vector<int>result;
        result.push_back(up+1);
        result.push_back(down+1);
        return result;
    }
};
leedcode 167

面试题57 - II. 和为s的连续正数序列

class Solution {
public:
    vector<vector<int>> findContinuousSequence(int target) {
        vector<vector<int>>result;
        int head=1,tail=1;
        int s=1;
        while(head<target)
        {
            if(s<target)
            {
                tail++;
                s+=tail;
            }
            else if(s>target)
            {
                s-=head;
                head++;
            }
            else if(s==target)
            {
                vector<int> tmp;
                for(int i=head;i<=tail;i++)
                {
                    tmp.push_back(i);
                }
                result.push_back(tmp);
                tail++;
                s+=tail;
            }
        }
        return result;
    }
};
View Code

 

 

 

三、其他指针

牛客 替换指针

有空间限制不能使用第二个数组转存,因此先遍历一遍统计空格‘ ’的数量,然后留足空间(2倍空格数量),

down指针从后往前扫,up指针从原串最后往前扫,碰到‘ ’就替换成‘0’‘2’‘%’,直到up down相撞

class Solution {
public:
    void replaceSpace(char *str,int length) {
        int num=0,i;
        for(i=0;str[i]!='\0';i++)
        {
            if(str[i]==' ')
                num++;
        }
        int len_final=i+num*2;
        char *down=str+len_final;
        char *up=str+i;
        while(up!=down)
        {
            if(*up==' ')
            {
                *down--='0';
                *down--='2';
                *down--='%';
            }
            else
                *down--=*up;
            up--;
        }
        return;
    }
};
View Code

 

56. 合并区间

#include<algorithm>
#include<string.h>
#include<stdlib.h>
struct donser
{
    int i;
    int j;
};
int qsor(const void* a,const void*b)
{
    return (*(donser *)a).i-(*(donser *)b).i;
}
class Solution {
public:
    vector<vector<int>> merge(vector<vector<int>>& inte) {
        vector<vector<int>>result;
        struct donser my[10002];
        if(inte.size()==0)
            return result;
        for(int i=0;i<inte.size();i++)
        {
            my[i].i=inte[i][0];
            my[i].j=inte[i][1];
        }
        qsort(my,inte.size(),sizeof(donser),qsor);
        my[inte.size()].i=inte[inte.size()-1][0];
        my[inte.size()].j=inte[inte.size()-1][1];
        int x=my[0].i,y=my[0].j;
        for(int i=0;i<inte.size()+1;i++)
        {
            if(x<=my[i].i&&y>=my[i].i)//有交集 更新y
            {
                y=max(y,my[i].j);
                if(i==inte.size())//处理最后
                {
                    vector<int>tmp;
                    tmp.push_back(x);
                    tmp.push_back(y);
                    result.push_back(tmp);
                }
            }
            else//无交集 存储
            {
                vector<int>tmp;
                tmp.push_back(x);
                tmp.push_back(y);
                result.push_back(tmp);
                if(i==inte.size())
                    break;
                x=my[i].i;
                y=my[i].j;
            }
        }
        return result;
    }
};
leetcode 56

 

75. 颜色分类

四指针,两个用于标记位置,两个用于查找
class Solution {
public:
    void sortColors(vector<int>& nums) {
        if(nums.size()<=1)
            return;
        int x=0,y=nums.size()-1;//扫描指针
        int x1=0,y1=nums.size()-1;//位置指针
        int equ1=0,equ2=0;//重合标记
        while(x<=y)
        {
            if(y!=y1)
                equ2=1;
            if(x!=x1)
                equ1=1;
            if(equ1==0)//前一半重合
            {
                if(nums[x]==0)//继续
                {
                    x++;
                    x1++;
                    continue;
                }
                else if(nums[x]==2)//交换
                {
                    if(nums[y]!=2)
                    {
                        int tmp=nums[x];
                        nums[x]=nums[y];
                        nums[y]=tmp;
                        continue;
                    }
                }
                else if(nums[x]==1)//处理
                {
                    equ1=1;
                    x++;
                    continue;
                }
            }
            if(equ2==0)//后一半重合
            {
                if(nums[y]==2)//继续
                {
                    y--;
                    y1--;
                    continue;
                }
                else if(nums[y]==0)//交换
                {
                    if(nums[x]!=0)
                    {
                        int tmp=nums[x];
                        nums[x]=nums[y];
                        nums[y]=tmp;
                        continue;
                    }
                    if(nums[x]==0)
                    {
                        equ2=1;
                    }
                }
                else if(nums[x]==1)//处理
                {
                    equ2=1;
                    y--;
                    continue;
                }
            }
            //处理x不重合情况
            if(nums[x]==2)//和y1交换
            {
                int tmp=nums[x];
                nums[x]=nums[y1];
                nums[y1]=tmp;
                y1--;
                y=min(y,y1);
                if(y1==y)
                    equ2=0;
            }
            else if(nums[x]==0)//和x1交换
            {
                int tmp=nums[x];
                nums[x]=nums[x1];
                nums[x1]=tmp;
                x1++;
                x=max(x,x1);
            }
            else if(nums[x]==1)
                x++;
            //处理y不重合情况
            if(nums[y]==2)//和y1交换
            {
                //cout<<"***"<<nums[y]<<" "<<nums[x]<<endl;
                int tmp=nums[y];
                nums[y]=nums[y1];
                nums[y1]=tmp;
                y1--;
                y=min(y,y1);
            }
            else if(nums[y]==0)//和x1交换
            {
                int tmp=nums[y];
                nums[y]=nums[x1];
                nums[x1]=tmp;
                x1++;
                x=max(x,x1);
                if(x1==x)
                    equ1=0;
            }
            else if(nums[y]==1)
                y--;
        }
        return ;
    }
};
leetcode 75

 

 

posted @ 2020-02-02 20:58  未名亚柳  阅读(734)  评论(1编辑  收藏  举报