当前位置:   article > 正文

探索算法系列 - 双指针

探索算法系列 - 双指针

目录

移动零(原题链接)

复写零(原题链接)

快乐数(原题链接)

盛最多水的容器(原题链接)

有效三角形的个数(原题链接)

查找总价格为目标值的两个商品(原题链接)

三数之和(原题链接)

四数之和(原题链接)


移动零(原题链接)

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

请注意 ,必须在不复制数组的情况下原地对数组进行操作。

解题思路

  • 定义两个指针 cur 和 dest
  • cur 用于遍历整个数组。
  • dest 指向下一个非零元素应该放置的位置。
  • 初始化 dest 为 -1,这是因为我们需要在第一次找到非零元素时将其值赋给 dest 并且增加 dest 的值。

步骤说明

  1. 初始化

    • cur 从0开始。
    • dest 从-1开始(表示还没有遇到非零元素)。
  2. 遍历数组

    • 使用循环遍历整个数组 nums
    • 对于数组中的每一个元素 nums[cur],检查它是否是非零元素。
      • 如果 nums[cur] 不为0,则执行以下操作:
        • 将 dest 加1。
        • 交换 nums[dest] 和 nums[cur] 的值。
  3. 结束条件

    • 当 cur 遍历完整个数组后,循环结束。
  4. 结果

    • 所有的非零元素都已经被移动到了数组的前半部分,并保持了原有的顺序。
    • 所有的0元素都被移动到了数组的后半部分。

具体代码

  1. class Solution
  2. {
  3. public:
  4. void moveZeroes(vector<int>& nums)
  5. {
  6. for (int cur = 0, dest = -1; cur < nums.size(); cur++)
  7. {
  8. if (nums[cur])
  9. {
  10. swap(nums[++dest], nums[cur]);
  11. }
  12. }
  13. }
  14. };

复写零(原题链接)

给你一个长度固定的整数数组 arr ,请你将该数组中出现的每个零都复写一遍,并将其余的元素向右平移。

注意:请不要在超过该数组长度的位置写入元素。请对输入的数组 就地 进行上述修改,不要从函数返回任何东西。

解题思路

  • 初始化变量

  • 预处理

  • 复制与调整

步骤说明

  1. 初始化

    • cur 从0开始。
    • dest 从-1开始。
    • n 是数组的长度。
  2. 预处理

    • 使用循环遍历整个数组 arr
    • 如果 arr[cur] 是0,则 dest 增加2;否则,dest 增加1。
    • 如果 dest 大于等于 n-1,则退出循环。
  3. 特殊情况处理

    • 如果 dest 等于 n,说明最后一个位置应该是一个复制的0元素,需要将最后一个元素设置为0,并减少 dest 的值以确保不会超出数组长度。
    • 减少 cur 的值以便在接下来的步骤中重新处理这个位置。
  4. 复制与调整

    • 从 cur 开始向左遍历数组。
    • 如果 arr[cur] 不为0,则直接将 arr[cur] 复制到 dest 的位置。
    • 如果 arr[cur] 为0,则需要复制两次0元素到 dest 的位置。
    • 在每一步之后减少 dest 的值,并且每次循环结束后减少 cur 的值。
  5. 结束条件

    • 当 cur 小于0 时,循环结束。

具体代码

  1. class Solution
  2. {
  3. public:
  4. void duplicateZeros(vector<int>& arr)
  5. {
  6. int cur = 0, dest = -1, n = arr.size();
  7. while (cur < n)
  8. {
  9. if (arr[cur])
  10. dest++;
  11. else
  12. dest += 2;
  13. if (dest >= n - 1)
  14. break;
  15. cur++;
  16. }
  17. if (dest == n)
  18. {
  19. arr[n - 1] = 0;
  20. cur--;
  21. dest -= 2;
  22. }
  23. while (cur >= 0)
  24. {
  25. if (arr[cur])
  26. arr[dest--] = arr[cur--];
  27. else
  28. {
  29. arr[dest--] = 0;
  30. arr[dest--] = 0;
  31. cur--;
  32. }
  33. }
  34. }
  35. };

快乐数(原题链接)

编写一个算法来判断一个数 n 是不是快乐数。

「快乐数」 定义为:

  • 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
  • 然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
  • 如果这个过程 结果为 1,那么这个数就是快乐数。

如果 n 是 快乐数 就返回 true ;不是,则返回 false 。

首先我们先证明:

        对于任意正整数,通过上述过程要么最终变为 1,要么进入一个循环,而不会出现其他情况。(鸽巢原理)

证明过程

  1. 有限性

    • 假设初始数为 
      声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/在线问答5/article/detail/906220
推荐阅读
相关标签