分类

  • 快慢指针:解决链表问题(如判断链表是否含环)
  • 左右指针:字符串或数组问题(如二分法)
  • 滑动窗口

快慢指针

初始化时,一般快慢指针都指向链表的head.

问题1:链表是否含环?

对于一般链表而言

  1. function hasCycle(head){
  2. while(head){
  3. head = head.next
  4. }
  5. return false
  6. }

但是这种情况对于环形链表就会陷入死循环。

  1. function hasCycle(head){
  2. let fast,slow;
  3. fast = slow = head;
  4. while(fast&&fast.next){
  5. fast = fast.next.next;
  6. slow = slow.next;
  7. if(fast===slow) return true;
  8. }
  9. return false;
  10. }

使用快慢指针后,快指针每次移动两步,慢指针每次移动一步,最终快指针比慢指针快一圈,即fast===slow

问题2:已知链表中含有环,返回这个环的起始位置?

不理解
**

问题3:寻找链表的中点

  1. function getMid(head){
  2. let fast,slow;
  3. fast = slow = head;
  4. while(fast&&fast.next){
  5. fast = fast.next.next;
  6. slow = slow.next
  7. }
  8. return slow;
  9. }

当fast移动2k步的时候,slow移动k步

问题4:寻找链表的倒数第 k 个元素

思路:先让fast移动k步,然后再让fast slow以同样的速度移动,当fast到达链表尾端的时候,slow就在倒数第k个元素。

  1. function getK(head,k){
  2. let fast,slow;
  3. fast = slow = head;
  4. while(k>0){
  5. fast = fast.next;
  6. k--;
  7. }
  8. while(fast){
  9. fast = fast.next;
  10. slow =slow.next;
  11. }
  12. return slow;
  13. }

左右指针常见用法

左右指针在数组中实际是指两个索引值,一般初始化为 left = 0, right = nums.length - 1

问题1:二分法

  1. function binarySearch(list,target){
  2. let left = 0,right= list.length-1;//左右均是闭区间
  3. while(left<=right){
  4. const mid = left +Math.floor((right-left)/2);
  5. if(list[mid]===target){
  6. return mid;
  7. }else if(list[mid]>target){
  8. right = mid-1;
  9. }else if(list[mid]<target){
  10. left = mid+1;
  11. }
  12. }
  13. return -1;
  14. }

问题2:两数之和

图片.png

  1. function twoSum(list,target){
  2. let left = 0,right = list.length-1;
  3. while(left<right){
  4. const sum = list[left]+list[right];
  5. if(sum===target)return [left,right]
  6. if(sum<target) left++;
  7. if(sum>target) right++;
  8. }
  9. return[-1,-1];
  10. }

问题3:反转数组

  1. function reverse(list){
  2. let left = 0,right=list.length-1;
  3. while(left<right){
  4. [list[left],list[rigth]] = [list[right],list[left]]
  5. left++;
  6. right--;
  7. }
  8. return list;
  9. }