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

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

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.有序数组的平方

相关推荐
coderSong25682 小时前
Java高级 |【实验八】springboot 使用Websocket
java·spring boot·后端·websocket
Mr_Air_Boy3 小时前
SpringBoot使用dynamic配置多数据源时使用@Transactional事务在非primary的数据源上遇到的问题
java·spring boot·后端
豆沙沙包?3 小时前
2025年- H77-Lc185--45.跳跃游戏II(贪心)--Java版
java·开发语言·游戏
年老体衰按不动键盘4 小时前
快速部署和启动Vue3项目
java·javascript·vue
咖啡啡不加糖4 小时前
Redis大key产生、排查与优化实践
java·数据库·redis·后端·缓存
liuyang-neu4 小时前
java内存模型JMM
java·开发语言
int型码农4 小时前
数据结构第八章(一) 插入排序
c语言·数据结构·算法·排序算法·希尔排序
UFIT4 小时前
NoSQL之redis哨兵
java·前端·算法
喜欢吃燃面4 小时前
C++刷题:日期模拟(1)
c++·学习·算法
刘 大 望4 小时前
数据库-联合查询(内连接外连接),子查询,合并查询
java·数据库·sql·mysql