Leetcode常见算法:【two pointers】双指针

80 阅读2分钟

分类

  • 普通双指针
  • 对撞双指针
  • 快慢双指针

对撞指针

设置头尾两个指针 L,R,分别往中间移动

Leetcode27. 移除元素

设置头尾两个指针 L,R,分别往中间移动

L指针指向为值为val时候的位置停下,R指针指向值不为val时候的位置停下,交换位置,把要删除的val全部丢到尾部去,最后双指针重叠时,返回从0开始到重叠的双指针位置。

最后需要判断两个在同一位置的指针的当前值是否为val,如果是则返回从0L指针位置的数组,如果不等于则0到返回L指针+1位置的数组。

class Solution {
    public int removeElement(int[] nums, int val) {

      if (nums==null || nums.length ==0){
        return 0;
      }
      int L =0;
      int R = nums.length-1;
      
      while(L< R){

        while( L<R && nums[L]!=val ){
            l+=1;
        }
        
        while(L<R && nums[R]==val) {
          r-=1;
        }
        
        // swap
        int temp = nums[L];
        nums[L] =nums[R];
        nums[R] = temp;
      }
      return nums[L]==val? L : L+1; 
    }
}

Leetcode 881. 救生艇

两数求和,还是可以用对撞指针的解法,先把数组原地排序,设置头尾两个指针,如果两个指针的数相加满足条件那么头和尾都往中间移动,满不满足,尾指针都得移动,概括的说就是,满足条件咱俩都能走,不满足单走末尾的胖子一个。

class Solution {
    public int numRescueBoats(int[] people, int limit) {

        if (people == null || limit == 0 ){
            return 0;
        }
        
        Arrays.sort(people);
        
        int num = 0; //返回数量
        
        int i = 0;
        
        int j = people.length - 1;
        
       while (i <= j) {
           
           if (people[i] + people[j] <= limit){    
              i++;
           }
           j--;
           num++;      
        }
        
        return num;


    }
}

快慢指针

两个指针同一起点,一快一慢

Leetcode26. 删除数组中的重复项

image.png

比较 p 和 q 位置的元素是否相等。

如果相等,q 后移 1 位 如果不相等,将 q 位置的元素复制到 p+1 位置上,p 后移一位,q 后移 1 位 重复上述过程,直到 q 等于数组长度。

返回 p + 1,即为新数组长度。

class Solution {
    public int removeDuplicates(int[] nums) {
        
        if (nums.length == 0 || nums == null){
            return 0;
        }
         
        int p = 0 ;
        int q = 1 ;
        
        while (q <  nums.length){
            if (nums[p]!=nums[q]){ 
                nums[p+1] = nums[q];
                p++;             
            }
            q++;      
        }

         return p+1;
 }
}