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

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

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

相关推荐
工业互联网专业5 分钟前
基于springboot+vue的社区药房系统
java·vue.js·spring boot·毕业设计·源码·课程设计·社区药房系统
郭涤生9 分钟前
C++ 完美转发
c++·算法
API小爬虫21 分钟前
如何用爬虫获得按关键字搜索淘宝商品
java·爬虫·python
whoarethenext44 分钟前
数据结构堆的c/c++的实现
c语言·数据结构·c++·
Codeking__1 小时前
滑动窗口——无重复字符最长的字串
算法·哈希算法
sanx181 小时前
从零搭建体育比分网站完整步骤
java·开发语言
夏季疯1 小时前
学习笔记:黑马程序员JavaWeb开发教程(2025.3.29)
java·笔记·学习
努力也学不会java1 小时前
【HTTP】《HTTP 全原理解析:从请求到响应的奇妙之旅》
java·网络·网络协议·http
Ten peaches1 小时前
苍穹外卖(订单状态定时处理、来单提醒和客户催单)
java·数据库·sql·springboot
caihuayuan52 小时前
全文索引数据库Elasticsearch底层Lucene
java·大数据·vue.js·spring boot·课程设计