【二刷代码随想录】双指针-数组相关题型、推荐习题

一、双指针-数组 相关题型与常用思路

1、单个数组

(1)原地移除元素类

如推荐习题中的(1)、(2)、(3),都属于此类。引入双指针 pre、last ,用 pre 指针表明数组的最后位置;用 last 指针结合 for 遍历数组,去寻找不符合题意的元素,将其插入有效数组中,也就是 pre 位置,从而达到原地处理的要求。

以题(2)为例:

java 复制代码
class Solution {
    public int removeDuplicates(int[] nums) {
        //慢指针:指向最终数组的最后元素
        int low = 0;
        //在比较中将第一个元素视为不同元素
        int res = 1;

        //快指针从1开始,因为要默认保存第一个元素,后面的元素再进行比较
        for(int fast = 1; fast < nums.length; fast++){
            //若重合,则过滤不保存;除非不重合,则保存该元素
            if(nums[fast] != nums[low]){
                res++;
                low++;
                nums[low] = nums[fast];
            }
        }

        return res;
    }
}

(2)特殊规则处理元素

如推荐习题中的(5),若要实现时间复杂度为 O(n),必然是使用双指针的。用双指针从数组的两侧往中间位置移动,直到遍历完所有元素。

java 复制代码
class Solution {
    public int[] sortedSquares(int[] nums) {
        int len = nums.length;

        int[] res = new int[len];

        int i,j,x;

        i = 0;
        j = len - 1;
        x = len - 1;

        //从两端往中间依次判定
        while(i <= j){
            if(Math.abs(nums[i]) >= Math.abs(nums[j])){
                res[x] = nums[i] * nums[i];
                i++;
            }else{
                res[x] = nums[j] * nums[j];
                j--;
            }
            x--;
        }
        
        return res;
    }
}

(3)滑动窗口--待补充

2、两个数组

一定规则下,比较两数组之间的关系,大多是相等关系。

如推荐习题中的(4),若要实现时间复杂度为 O(m+n),必然是使用双指针的。结合提意,此题需要从尾部开始遍历,遇见特殊字符时,做好标记,以便直接跳过后续的字符。

java 复制代码
class Solution {
    public boolean backspaceCompare(String s, String t) {
        int sLen = s.length();
        int tLen = t.length();

        int p1 = sLen - 1;
        int p2 = tLen - 1;

        int skipS = 0;
        int skipT = 0;

        //倒序处理字符串
        while(p1 >= 0 || p2 >= 0){
            while(p1 >= 0){
                if(s.charAt(p1) == '#'){    //  为退格符,则增加退格符数量
                    skipS++;
                    p1--;
                }else{                      
                    if(skipS > 0){           //  为字母,且退格符数量为正数,则减少退格符数量   
                        skipS--;
                        p1--;
                    }else{                  //  为字母,且退格符数量为0,则退出当轮循环
                        break;
                    }
                }
            }

            while(p2 >= 0){
                if(t.charAt(p2) == '#'){    //  为退格符,则增加更退格符数量
                    skipT++;
                    p2--;
                }else{                      
                    if(skipT > 0){          //  为字母,且退格符数量为正数,则减少退格符数量  
                        skipT--;
                        p2--;
                    }else{                  //  为字母,且退格符数量为0,则退出当轮循环
                        break;
                    }
                }
            }

            if(p1 >= 0 && p2 >= 0){         //对比两个字符串中有效字符是否相同
                if(s.charAt(p1) == t.charAt(p2)){
                    p1--;
                    p2--;
                }else{
                    return false;
                } 
            }else if(p1 < 0 && p2 >= 0 || p1 >= 0 && p2 < 0){   //或有一方已为空,而另一方不为空【若不处理会导致死循环!!】
                return false;
            }
        }

        if(p1 > 0 || p2 > 0){               //若经过上述比较,仍然存在至少一方不为空,则表明两字符不相同
            return false;
        }

        return true;
    }
}

二、推荐习题

(1)原地 移除元素

27.移除元素

给你一个数组 nums和一个值 val,你需要 原地 移除所有数值等于 val的元素。元素的顺序可能发生改变。然后返回 nums 中与 val 不同的元素的数量。

假设 nums 中不等于 val 的元素数量为 k,要通过此题,您需要执行以下操作:

  • 更改 nums 数组,使 nums 的前 k 个元素包含不等于 val 的元素。nums 的其余元素和 nums 的大小并不重要。
  • 返回 k

(2)原地 删除有序数组的重复项

26.删除排序数组中的重复项

给你一个 非严格递增排列 的数组 nums ,请你**原地** 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。

考虑 nums 的唯一元素的数量为 k ,你需要做以下事情确保你的题解可以被通过:

  • 更改数组 nums ,使 nums 的前 k 个元素包含唯一元素,并按照它们最初在 nums 中出现的顺序排列。nums 的其余元素与 nums 的大小不重要。
  • 返回 k

(3)原地 移除目标值到数组末尾

283.移动零

(4)比较有效字符串

844.比较含退格的字符串

(5)对有序数组元素的平方值,形成新有序数组

977.有序数组的平方

相关推荐
冬天vs不冷37 分钟前
EasyExcel导出自动回显中文,读取自动转换码值(基于全局转换器与自定义注解)
java·excel
阿里云云原生40 分钟前
RAG 调优指南:Spring AI Alibaba 模块化 RAG 原理与使用
java·人工智能·spring
天上掉下来个程小白44 分钟前
Redis-12.在Java中操作Redis-Spring Data Redis使用方式-操作字符串类型的数据
java·redis·spring·springboot·苍穹外卖
f狐0狸x2 小时前
【蓝桥杯每日一题】4.1
c语言·c++·算法·蓝桥杯
ん贤2 小时前
2023第十四届蓝桥杯大赛软件赛省赛C/C++ 大学 B 组(真题&题解)(C++/Java题解)
java·c语言·数据结构·c++·算法·蓝桥杯
梭七y2 小时前
【力扣hot100题】(022)反转链表
算法·leetcode·链表
在京奋斗者4 小时前
spring boot自动装配原理
java·spring boot·spring
威视锐科技5 小时前
软件定义无线电36
网络·网络协议·算法·fpga开发·架构·信息与通信
牧歌悠悠5 小时前
【Python 算法】动态规划
python·算法·动态规划
JINX的诅咒5 小时前
CORDIC算法:三角函数的硬件加速革命——从数学原理到FPGA实现的超高效计算方案
算法·数学建模·fpga开发·架构·信号处理·硬件加速器