【力扣】移除元素(使用双指针)--引出边界判断难题:while 循环条件中是否加等号的问题

问题描述

在这里插入图片描述

第一次解题存在问题<方法2中while条件注释部分–问题点:缺少等号>

class Solution {
    public int removeElement(int[] nums, int val) {
        //方法1
        //思路:利用双指针+选择排序
        //从头遍历,不相等则交换
        //p1为for循环时i后面(包含i)的第一个不等于val的位置
        int p1=0;
        for(int i=0;i<nums.length;i++){
            if(nums[i]!=val){
                nums[p1]=nums[i];
                p1++;
            }
        }
        return p1;
        
        //方法2 优化双指针
        int p1=0;
        int p2=nums.length-1;
        int current = 0;
        //while(p1<p2){  //第一遍解题答案中,判定条件为p1<p2,缺少=
        while(p1<=p2){
            if(nums[p1]==val){
                nums[p1]=nums[p2];
                p2--;
            }else{
                p1++;
            }
        }
        return p1;
    }
}

第一次解题错误的问题和原因

问题代码(注释部分)

        //while(p1<p2){  //第一遍解题答案中,判定条件为p1<p2,缺少=
        while(p1<=p2){
            if(nums[p1]==val){
                nums[p1]=nums[p2];
                p2--;
            }else{
                p1++;
            }
        }

导致结果
在这里插入图片描述
原因:
p1 < p2而不是p1 < =p2时
移动方式​:当 nums[p1]==val 时,只移动 p2 不移动 p1,当前位置仍需要处理
中间元素处理​:当 p1 == p2 时,这个元素尚未处理
边界测试​:单元素数组 [2], val=2:应返回长度0,p1=0, p2=0 → 如果不用 <=,循环根本不执行

技术细节


小结

解决边界判断难题:while 循环条件中是否加等号?
在双指针算法中,判断循环条件是使用 left < right 还是 left <= right 是一个常见痛点

判断技巧 - “三看原则”
第一看:看指针移动方式

移动特点推荐条件例子
​移动后直接跳过当前元素​(如 left++ 或 right–)left <= right二分查找:left = mid + 1
移动后仍处理当前元素​(如不移动或移动但不跳过)left < right快慢指针:slow = slow.next

第二看:看终止时中间元素是否需处理

中间元素状态推荐条件例子
相遇点需要处理left <= right移除元素中需检测最后单个元素
相遇点无需处理left < right两数之和中左右指针不能重合

第三看:看边界测试用例
用特殊边界值验证循环条件:
1.​空数组测试​:[]
​2.单元素数组​:[1]
​3.双元素数组​:[1,2]

决策流程图

在这里插入图片描述

通用解决方案 - 调试模板

当不确定循环条件时,使用这个调试模板:

int left = ..., right = ...;
// 先用最保险的条件
while (left <= right) { // 保险包含等号
    // 核心逻辑...
    
    // 增加安全保护
    if (left == right) {
        // 处理最后单个元素
        // ...
        break; // 处理后退出
    }
}

常见算法条件总结表

算法类型推荐条件解释
​二分查找​left <= right需处理最后单个元素
​两数之和​left < right左右指针不能重合
​快慢指针​fast != null && fast.next != null防止空指针异常
​滑动窗口​right < nums.length右指针遍历到结尾
​原地移除元素​left <= right处理最后单个元素

终极心法

​当犹豫不决时,先用 left <= right 确保中间元素被处理,然后通过测试用例验证是否能优化为 left < right
通过系统化分析指针移动方式、中间元素处理需求和边界测试,结合调试模板,就能在双指针算法中处理循环条件问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值