双指针窗口题目(简单)

1.Pair with Target Sum (easy)

问题描述

给定一个排序数字数组和一个目标总和,在数组中找到一个总和等于给定目标的对。

编写一个函数来返回两个数字(即对)的索引,以便它们相加到给定的目标。
Example 1:

Input: [1, 2, 3, 4, 6], target=6
Output: [1, 3]
Explanation: The numbers at index 1 and 3 add up to 6: 2+4=6

Example 2:

Input: [2, 5, 9, 11], target=11
Output: [0, 2]
Explanation: The numbers at index 0 and 2 add up to 11: 2+9=11

解题的关键:

1.首先注意数组是有序的由于给定的数组已排序,暴力解决方案可能是遍历数组,一次取一个数字并通过二分法搜索第二个数字。 该算法的时间复杂度为 O(N*logN)
我们可以考虑双指针的方法。 我们将从一个指向数组开头的指针和另一个指向数组末尾的指针开始。 在每一步,我们将查看两个指针指向的数字加起来是否等于目标总和。 如果等于的话,我们就找到了我们的配对; 否则,我们将做以下两件事之一:

如果两个指针指向的两个数之和大于目标和,这意味着我们需要一个和较小的对。 因此,要尝试更多对,我们可以向后移动尾部指针。
如果两个指针指向的两个数之和小于目标和,这意味着我们需要一个和更大的对。 因此,要尝试更多对,我们可以向前移动头部指针。

这也是双指针解法的基本模板

    int left = 0, right = arr.size() - 1;
    while (left < right) {
      int currentSum = arr[left] + arr[right];
      if (currentSum == targetSum) { // found the pair
        return make_pair(left, right);
      }

      if (targetSum > currentSum)
        left++; // we need a pair with a bigger sum
      else
        right--; // we need a pair with a smaller sum
    }
    return make_pair(-1, -1);
  }

2.Remove Duplicates (easy)

给定一个排序数字数组,从中删除所有重复项。 不可以使用任何额外的空间; 在就地删除重复项后,返回其中没有重复项的子数组的长度。

Input: [2, 3, 3, 3, 6, 9, 9]
Output: 4
Explanation: The first four elements after removing the duplicates will be [2, 3, 6, 9].

Example 2:

Input: [2, 2, 2, 11]
Output: 2
Explanation: The first two elements after removing the duplicates will be [2, 11].

解题的关键:

1.首先要知道不可以使用额外的空间,只能在数组内部操作。然后要找到集合是不需要计算和的,所以也么必要一个放到数组头,一个放到数组尾部。两个指针都放到数组头,一个指针一直向前走,我们叫它指针一,另一个指针指向一个位置,在这个位置之前的数组是没有重复的,我们叫它指针二。要注意数组是有序的,我们只需要在指针一指向的数,跟指针二指向的数前面一个不同,然后用指针一指向的数替换指针二指向的数即可。说的有点抽象,来个图解释一下:
在这里插入图片描述

 static int remove(vector<int>& arr) {
    int nextNonDuplicate = 1;  
    // 因为要跟前面的一个数比较,所以从开始时指向数组的第二个数
    for (int i = 0; i < arr.size(); i++) {
      if (arr[nextNonDuplicate - 1] != arr[i]) {
        arr[nextNonDuplicate] = arr[i];
        nextNonDuplicate++;
      }
    }

    return nextNonDuplicate;
  }

还有一题与上题相似:
给定一个未排序的数字数组和一个目标“key”,就地删除“key”的所有实例并返回数组的新长度。

Input: [3, 2, 3, 6, 3, 10, 9, 3], Key=3
Output: 4
Explanation: The first four elements after removing every 'Key' will be [2, 6, 10, 9].

Example 2:

Input: [2, 11, 2, 2, 1], Key=2
Output: 2
Explanation: The first two elements after removing every 'Key' will be [11, 1].
 int remove(vector<int>& arr, int key) {
    int nextElement = 0; 
    //注意要从数组的第一个数开始判断
    for (int i = 0; i < arr.size(); i++) {
      if (arr[i] != key) {
        arr[nextElement] = arr[i];
        nextElement++;
      }
    }

    return nextElement;

3.Squaring a Sorted Array (easy)

问题描述

给定一个排序数字数组和一个目标总和,在数组中找到一个总和等于给定目标的对。

编写一个函数来返回两个数字(即对)的索引,以便它们相加到给定的目标。
Example 1:

Input: [-2, -1, 0, 2, 3]
Output: [0, 1, 4, 4, 9]

Example 2:

Input: [-3, -1, 0, 1, 2]
Output: [0, 1, 1, 4, 9]

解题的关键:

1.数组是有序的,数组中有负数,两个指针分别指向数组的首尾,比较一下首尾元素平凡后的大小,将较大的放入即可

 vector<int> makeSquares(const vector<int>& arr) {
    int n = arr.size();
    vector<int> squares(n);
    int highestSquareIdx = n - 1;
    int left = 0, right = n - 1;
    while (left <= right) {
      int leftSquare = arr[left] * arr[left];
      int rightSquare = arr[right] * arr[right];
      if (leftSquare > rightSquare) {
        squares[highestSquareIdx--] = leftSquare;
        left++;
      } else {
        squares[highestSquareIdx--] = rightSquare;
        right--;
      }
    }
    return squares;
  }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值