代码随想录 数组-02-移除元素

双指针法

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

定义快慢指针

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

很多同学这道题目做的很懵,就是不理解 快慢指针究竟都是什么含义,所以一定要明确含义,后面的思路就更容易理解了。

删除过程如下:

代码随想录 数组-02-移除元素_第1张图片

class Solution {
    public int removeElement(int[] nums, int val) {
        // 快慢指针
        int slowIndex = 0;
        for (int fastIndex = 0; fastIndex < nums.length; fastIndex++) {
            if (nums[fastIndex] != val) {
                nums[slowIndex] = nums[fastIndex];
                slowIndex++;
            }
        }
        return slowIndex;
    }
}
 //相向双指针法
class Solution {
    public int removeElement(int[] nums, int val) {
        int left = 0;
        int right = nums.length - 1;
        while(right >= 0 && nums[right] == val) right--; //将right移到从右数第一个值不为val的位置
        while(left <= right) {
            if(nums[left] == val) { //left位置的元素需要移除
                //将right位置的元素移到left(覆盖),right位置移除
                nums[left] = nums[right];
                right--;
            }
            left++;
            while(right >= 0 && nums[right] == val) right--;
        }
        return left;
    }
}
 // 相向双指针法(版本二)
class Solution {
    public int removeElement(int[] nums, int val) {
        int left = 0;
        int right = nums.length - 1;
        while(left <= right){
            if(nums[left] == val){
                nums[left] = nums[right];
                right--;
            }else {
                // 这里兼容了right指针指向的值与val相等的情况
                left++;
            }
        }
        return left;
    }
}

 27.移除元素

27. 移除元素

简单

提示

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。

不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组

元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

class Solution {
    public int removeElement(int[] nums, int val) {
        int slow = 0;  // 慢指针,用于记录不等于目标值的元素的位置

        // 快指针遍历数组
        for (int fast = 0; fast < nums.length; fast++) {
            // 如果当前元素不等于目标值,将其移到慢指针位置,然后慢指针和快指针均向前移动
            if (nums[fast] != val) {
                nums[slow++] = nums[fast];
            }
        }

        return slow;  // 返回新数组的长度
    }
}

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

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

简单

提示

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

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

  • 更改数组 nums ,使 nums 的前 k 个元素包含唯一元素,并按照它们最初在 nums 中出现的顺序排列。nums 的其余元素与 nums 的大小不重要。
  • 返回 k 。
class Solution {
    public int removeDuplicates(int[] nums) {
        int slow = 0;  // 慢指针,用于记录不同元素的位置

        // 快指针遍历数组
        for (int fast = 0; fast < nums.length; fast++) {
            // 如果当前元素不等于慢指针位置的元素,将其移到慢指针位置,然后慢指针和快指针均向前移动
            if (nums[fast] != nums[slow]) {
                nums[++slow] = nums[fast];
            }
        }

        return slow + 1;  // 返回新数组的长度
    }
}

283.移动零

283. 移动零

简单

提示

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

请注意 ,必须在不复制数组的情况下原地对数组进行操作。

示例 1:

输入: nums = [0,1,0,3,12]
输出: [1,3,12,0,0]

示例 2:

输入: nums = [0]
输出: [0]

提示:

  • 1 <= nums.length <= 104
  • -231 <= nums[i] <= 231 - 1

进阶:你能尽量减少完成的操作次数吗?

class Solution {
    public void moveZeroes(int[] nums) {
        int slow = 0;  // 慢指针,用于记录非零元素的位置

        // 快指针遍历数组
        for (int fast = 0; fast < nums.length; fast++) {
            // 如果当前元素不为0,将其与慢指针位置的元素交换,然后慢指针和快指针均向前移动
            if (nums[fast] != 0) {
                int temp = nums[slow];
                nums[slow++] = nums[fast];
                nums[fast] = temp;
            }
        }
    }
}

844.比较含退格的字符串

844. 比较含退格的字符串

简单

给定 s 和 t 两个字符串,当它们分别被输入到空白的文本编辑器后,如果两者相等,返回 true 。# 代表退格字符。

注意:如果对空文本输入退格字符,文本继续为空。

示例 1:

输入:s = "ab#c", t = "ad#c"
输出:true
解释:s 和 t 都会变成 "ac"。

示例 2:

输入:s = "ab##", t = "c#d#"
输出:true
解释:s 和 t 都会变成 ""。

示例 3:

输入:s = "a#c", t = "b"
输出:false
解释:s 会变成 "c",但 t 仍然是 "b"。

提示:

  • 1 <= s.length, t.length <= 200
  • s 和 t 只含有小写字母以及字符 '#'

进阶:

  • 你可以用 O(n) 的时间复杂度和 O(1) 的空间复杂度解决该问题吗?
class Solution {
    public boolean backspaceCompare(String s, String t) {
        s = getTrueChar(s);  // 处理字符串s,去除退格符后的真实字符
        t = getTrueChar(t);  // 处理字符串t,去除退格符后的真实字符
        return s.equals(t);  // 比较两个处理后的字符串是否相等
    }

    /**
     * 处理字符串,去除退格符后的真实字符
     *
     * @param a 给定字符串
     * @return 处理后的字符串
     */
    public String getTrueChar(String a) {
        int slow = 0;  // 慢指针,用于记录处理后的字符串的位置

        // 快指针遍历字符串
        for (int fast = 0; fast < a.length(); fast++) {
            // 如果当前字符不为'#',将其放入慢指针位置覆盖
            if (a.charAt(fast) != '#') {
                a = a.substring(0, slow) + a.charAt(fast) + a.substring(slow + 1);
                slow++;
            } else {
                slow = Math.max(0, slow - 1);  // 如果当前字符为'#',将慢指针指向前一位,等待后边不为'#'的字符覆盖
            }
        }

        return a.substring(0, slow);  // 返回处理后的字符串
    }
}
//参考答案
class Solution {
    public boolean backspaceCompare(String s, String t) {
        s = func(s);
        t = func(t);
        return s.equals(t);
    }

    private String func(String s) {
        StringBuilder tmp = new StringBuilder();
        for (char ch : s.toCharArray()) {
            if (tmp.length() > 0 && ch == '#') {
                tmp.deleteCharAt(tmp.length() - 1);
            } else if (ch != '#') {
                tmp.append(ch);
            }
        }
        return tmp.toString();
    }
}

977.有序数组的平方

977. 有序数组的平方

简单

给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。

示例 1:

输入:nums = [-4,-1,0,3,10]
输出:[0,1,9,16,100]
解释:平方后,数组变为 [16,1,0,9,100]
排序后,数组变为 [0,1,9,16,100]

示例 2:

输入:nums = [-7,-3,2,3,11]
输出:[4,9,9,49,121]

提示:

  • 1 <= nums.length <= 104
  • -104 <= nums[i] <= 104
  • nums 已按 非递减顺序 排序

进阶:

  • 请你设计时间复杂度为 O(n) 的算法解决本问题
//利用非递减顺序,比较两头的平方哪个更大放入数组中
class Solution {
    public int[] sortedSquares(int[] nums) {
        int n = nums.length;
        int[] ans = new int[n];

        // 使用双指针从两端向中间遍历
        for (int i = 0, j = n - 1, pos = n - 1; i <= j;) {
            // 比较平方值大小,较大的平方值放在结果数组的末尾
            if (nums[i] * nums[i] > nums[j] * nums[j]) {
                ans[pos] = nums[i] * nums[i];
                ++i;
            } else {
                ans[pos] = nums[j] * nums[j];
                --j;
            }
            --pos;
        }

        return ans;
    }
}

你可能感兴趣的:(代码随想录,算法,leetcode,数据结构)