算法学习 02
1.删除有序数组中的重复项
给你一个 非严格递增排列 的数组 nums
,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums
中唯一元素的个数。
考虑 nums
的唯一元素的数量为 k
,你需要做以下事情确保你的题解可以被通过:
- 更改数组
nums
,使nums
的前k
个元素包含唯一元素,并按照它们最初在nums
中出现的顺序排列。nums
的其余元素与nums
的大小不重要。 - 返回
k
。 -
示例 1:
输入:nums = [1,1,2] 输出:2, nums = [1,2,_] 解释:函数应该返回新的长度
2,并且原数组 nums 的前两个元素被修改为1, 2 。
不需要考虑数组中超出新长度后面的元素。示例 2:
输入:nums = [0,0,1,1,1,2,2,3,3,4] 输出:5, nums = [0,1,2,3,4] 解释:函数应该返回新的长度 5,并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4。不需要考虑数组中超出新长度后面的元素。
-
class Solution {/*** 移除有序数组中的重复元素,返回移除后数组的新长度* 注:该方法会修改原数组,将不重复元素保留在数组前部* * @param nums 输入的有序整数数组(假设已按非递减顺序排列)* @return 移除重复元素后数组的新长度*/public int removeDuplicates(int[] nums) {// 处理边界情况:如果数组为空或长度为0,直接返回0if(nums == null || nums.length == 0) return 0;// 慢指针p:指向当前已处理的最后一个不重复元素的位置int p = 0;// 快指针q:用于遍历整个数组,寻找新的不重复元素int q = 1;// 遍历数组,直到快指针到达末尾while(q < nums.length){// 当快慢指针指向的元素不同时,说明找到了新的不重复元素if(nums[p] != nums[q]){// 将新元素放到慢指针的下一个位置nums[p + 1] = nums[q];// 慢指针向前移动一位,指向最新的不重复元素p++;}// 快指针继续向前移动,检查下一个元素q++;}// 慢指针的索引+1即为不重复元素的个数(新数组长度)return p + 1;} }
2.删除有序数组中的重复项Ⅱ
-
给你一个有序数组
nums
,请你 原地 删除重复出现的元素,使得出现次数超过两次的元素只出现两次 ,返回删除后数组的新长度。不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
-
示例 1:
输入:nums = [1,1,1,2,2,3] 输出:5, nums = [1,1,2,2,3] 解释:函数应返回新长度 length = 5, 并且原数组的前五个元素被修改为 1, 1, 2, 2, 3。 不需要考虑数组中超出新长度后面的元素。
示例 2:
输入:nums = [0,0,1,1,1,1,2,3,3] 输出:7, nums = [0,0,1,1,2,3,3] 解释:函数应返回新长度 length = 7, 并且原数组的前七个元素被修改为 0, 0, 1, 1, 2, 3, 3。不需要考虑数组中超出新长度后面的元素。
-
class Solution {public int removeDuplicates(int[] nums) {// 边界情况处理:如果数组长度小于等于2,直接返回原长度if (nums.length <= 2) {return nums.length;}int stackSize = 2; // 栈的大小,前两个元素默认保留(最多允许两个重复)// 从第三个元素开始遍历数组for (int i = 2; i < nums.length; i++) {// 和栈顶下方的元素比较,如果不同则可以加入栈中// 这样保证了栈中相同元素不会超过两个if (nums[i] != nums[stackSize - 2]) {nums[stackSize] = nums[i]; // 入栈,栈大小加1stackSize++;}}return stackSize; // 返回栈的大小,即处理后数组的长度} }