双指针总结

流过昼夜 提交于 2020-02-18 14:51:08

给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。

不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。

示例 1:

给定数组 nums = [1,1,2],

函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2。

你不需要考虑数组中超出新长度后面的元素。
示例 2:

给定 nums = [0,0,1,1,1,2,2,3,3,4],

函数应该返回新的长度 5, 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4。

你不需要考虑数组中超出新长度后面的元素。

我们使用i,j两个二指针, j 在前面走。如果 j 指向的元素等于 i 指向的元素 j 直接向前移,如果 j 指向的元素不等于 i 指向的元素,i 向前移 ,将 j 指向的元素赋给 i ,j向前移

 

    public int removeDuplicates(int[] nums) {
        int i=0;
        for(int j=1;j<nums.length;++j){
            if(nums[j] != nums[i]){
                if(j-i != 1){
                    nums[++i]=nums[j];
                }
                else{
                    ++i; //i,j相邻 直接 ++i
                }
            }
        }
        return i+1;
    }

 

给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数。

函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2。

说明:

返回的下标值(index1 和 index2)不是从零开始的。
你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。
示例:

输入: numbers = [2, 7, 11, 15], target = 9
输出: [1,2]
解释: 2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。

    public int[] twoSum(int[] numbers, int target) {
        int i=0,j=numbers.length-1;
        while(i<j){
            if(numbers[j]+numbers[i] >target){
                --j;
            }
            else if(numbers[j]+numbers[i] <target){
                ++i;
            }else{
                break;
            }
        }
        return new int[]{i+1,j+1};
    }

 

 

给定一个整数数组和一个整数 k, 你需要在数组里找到不同的 k-diff 数对。这里将 k-diff 数对定义为一个整数对 (i, j), 其中 i 和 j 都是数组中的数字,且两数之差的绝对值是 k.

示例 1:

输入: [3, 1, 4, 1, 5], k = 2
输出: 2
解释: 数组中有两个 2-diff 数对, (1, 3) 和 (3, 5)。
尽管数组中有两个1,但我们只应返回不同的数对的数量。
示例 2:

输入:[1, 2, 3, 4, 5], k = 1
输出: 4
解释: 数组中有四个 1-diff 数对, (1, 2), (2, 3), (3, 4) 和 (4, 5)。
示例 3:

输入: [1, 3, 1, 5, 4], k = 0
输出: 1
解释: 数组中只有一个 0-diff 数对,(1, 1)。
注意:

数对 (i, j) 和数对 (j, i) 被算作同一数对。
数组的长度不超过10,000。
所有输入的整数的范围在 [-1e7, 1e7]。

 

 

我们先将整数数组排序, 从第一个元素开始 向右寻找 diff 为 k 的元素

    public int findPairs(int[] nums, int k) {
        int res = 0;
        Arrays.sort(nums);
        int j=0;
        for(int i=0;i<nums.length-1;i++){

            //去掉相同元素
            for(;i>0&&i<nums.length&&nums[i]==nums[i-1];i++);
       //向右寻找
            j=i+1;
            for(;j<nums.length&&nums[j]-nums[i]<k;j++);
            
            if(j<nums.length&&nums[j]-nums[i]==k)
                res++;
        }
        return res;
    }

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!