给自己复盘的随想录笔记-移除元素

双指针法

双指针法(快慢指针法): 通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。

定义快慢指针

  • 快指针:寻找新数组的元素 ,新数组就是不含有目标元素的数组
  • 慢指针:指向更新 新数组下标的位置

相关题目

删除有序数组中的重复项

解题思路:
解法: 双指针

首先注意数组是有序的,那么重复的元素一定会相邻。

要求删除重复元素,实际上就是将不重复的元素移到数组的左侧。

考虑用 2 个指针,一个在前记作 p,一个在后记作 q,算法流程如下:

1.比较 p 和 q 位置的元素是否相等。

如果相等,q 后移 1 位
如果不相等,将 q 位置的元素复制到 p+1 位置上,p 后移一位,q 后移 1 位
重复上述过程,直到 q 等于数组长度。

返回 p + 1,即为新数组长度。

class Solution {
    public int removeDuplicates(int[] nums) {
    if(nums == null || nums.length == 0) return 0;
    int p = 0;
    int q = 1;
    while(q < nums.length){
        if(nums[p] != nums[q]){
            nums[p + 1] = nums[q];
            p++;
        }
        q++;
    }
    return p + 1;
}


}

移动零

有一个比较凑巧的思路,那就是知道后面是0 ,那么就去补0

class Solution {
    public void moveZeroes(int[] nums) {
     int slow=0;
     for(int fast=0;fast<nums.length;fast++){
        if(nums[fast]!=0){
            nums[slow++]=nums[fast];
        }
    
     }
     
     for( int num=slow;num<nums.length;num++){
        nums[num]=0;
     }
    }
}

另一种思路就是今天讲的双指针法,一个快指针指要交换的元素,一个满指针指元素接下来位置的下标,设计到元素的交换

class Solution {
    public void moveZeroes(int[] nums) {
        int n = nums.length, left = 0, right = 0;
        while (right < n) {
            if (nums[right] != 0) {
                swap(nums, left, right);
                left++;
            }
            right++;
        }
    }

    public void swap(int[] nums, int left, int right) {
        int temp = nums[left];
        nums[left] = nums[right];
        nums[right] = temp;
    }
}

比较含退格的字符串

思路:双指针: 遇到字母两指针都向前一位,遇到#号快指针向前一位,慢指针后退一位(注意0位置) 就行了。

这个思路好理解,我自己也想出来了,就是灵活运用双指针的思路,一定记住加上i>0的判断之后然后后移,避免出现第一个字符量就是#,不加上就会数组越界

class Solution {
    public boolean backspaceCompare(String s, String t) {
        char[] ss = s.toCharArray();
        char[] tt = t.toCharArray();

        return helper(ss).equals(helper(tt));
    }

    String helper(char[] c){
        int i = 0,j = 0;
        while(j < c.length){
            if(c[j] != '#'){ //遇到字母 两个指针都往前走
                c[i++] = c[j++];
            }else {
                j++;
                if(i > 0) i--;  // 遇到 #, i 指针向后退
            }
        }
        return new String(c).substring(0,i);
    }
}

这个地方数组字符串之间的转换要熟练把握。

有序数组的平方

这个题目不使用双指针的思路去做

class Solution {
    public int[] sortedSquares(int[] nums) {
   
for(int i=0;i<nums.length;i++){
nums[i]=nums[i]*nums[i];
    }
    Arrays.sort(nums);
    return nums;
}
    }

使用双指针的思路去做,

977. 有序数组的平方 - 力扣(LeetCode)

在评论区看到一个这道题用双指针的解法分析的很清晰的,

class Solution {
        public int[] sortedSquares(int[] nums) {
        // 左指针,指向原数组最左边
        int left = 0;
        // 有指针,指向原数组最右边
        int right = nums.length - 1;
        // 创建一个新数组,存储平方值
        int[] result = new int[nums.length];
        // 得到元素值平方值,从新数组最后位置开始写
        int write = nums.length - 1;
        // 左右指针相遇(逐渐靠拢的过程)之后不再循环
        while (left <= right){
            // 如果原数组的左指针对应的平方值大于右指针,那么往新数组最后位置写入左指针对应的平方值
            if (nums[left] * nums[left] > nums[right] * nums[right]){
                result[write] = nums[left] * nums[left];
                // 左指针右移
                left ++;
                // 移动新数组待写入的位置
                write --;
            }
            else {
                result[write] = nums[right] * nums[right];
                right --;
                write --;
            }
        }
        return result;
    }

}

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值