一、快慢指針: 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; } };

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; }
二、對撞指針: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 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 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; } };
面試題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; } };
三、其他指針
有空間限制不能使用第二個數組轉存,因此先遍歷一遍統計空格‘ ’的數量,然后留足空間(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; } };
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; } };
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 ; } };