一、快慢指针: 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]!='