26. 删除有序数组中的重复项(Leetcode/力扣)

题目:

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

由于在某些语言中不能改变数组的长度,所以必须将结果放在数组nums的第一部分。更规范地说,如果在删除重复项之后有 k 个元素,那么 nums 的前 k 个元素应该保存最终结果。

将最终结果插入 nums 的前 k 个位置后返回 k 。

不要使用额外的空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。

 

判题标准:

系统会用下面的代码来测试你的题解:

int[] nums = [...]; // 输入数组
int[] expectedNums = [...]; // 长度正确的期望答案

int k = removeDuplicates(nums); // 调用

assert k == expectedNums.length;
for (int i = 0; i < k; i++) {
    assert nums[i] == expectedNums[i];
}

代码:

class Solution {
  public int removeDuplicates(int[] nums) {
        //获得数组长度
        int length = nums.length;
        //用于递增判断是否与下面的值相等的数
        int num = nums[0];
        //用于返回的个数(因为是从高到低减少,所以默认未数组长度)
        int count = length;
        //用于记录某个下标需要替换的位置(因为第一个数肯定不会被换、默认为0)
        int temp =1;
        //如果为0直接返回
        if (length == 0) {
            return 0;
        }else {
        //因为判断中会有i+1的情况,所以不用考虑最后一个值
            for (int i = 0; i < length-1; i++) {
                if (num == nums[i+1]){
        //如果有数值相等  个数减1
                    count--;
                }else {
        //如果不是想等,将后面一个值赋给num,用于递增
                    num = nums[i+1];
                    nums[temp]=nums[i+1];
        //因为不相等,所以temp需要往后移位
                    temp++;
                }
            }
            return count;
        }
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
解题思路: 题目要求我们寻找一个最短的子数组,使得删去它之后原数组变成非递减数组。那么我们可以考虑贪心策略。首先,我们需要找到最长的非递减子数组,这个子数组在最后的答案肯定是不会被删除的,因为删去这个子数组回导致整个数组非递减性质被破坏。接着我们假设这个子数组的右端点为 i(当然我们还不知道实际的值是多少),那么我们接着考虑如何从左边找到最短的子数组,使得删去这个子数组之后原数组变为非递减数组。假设我们找到了左端点为 j 的子数组,那么这个子数组的长度就是 i-j-1。然后我们可以用一个变量 cnt 来统计需要从这个子数组删去的数字的个数,这个变量的初始化值为 0,每当我们找到一个子数组的边界,而这个子数组又不是非递减的时候,我们就将这个子数组从小到大排列的数字删掉并且让 cnt++。最终答案就是 i-j-1-cnt,即最长的非递减子数组长度减去从左边找到的最短需要删除的子数组的长度再减去被删除数字个数。 具体实现可以使用单调栈,单调栈里存的是数组元素的下标,栈顶到栈底位置对应的元素值是单调不降的。遍历数组的时候,如果当前元素比单调栈的栈顶小,说明需要找到右端点,于是不断pop出深度直到栈顶元素小于当前元素或者栈空,此时当前元素的下标就是右端点。接着我们在单调栈里寻找左端点,这里需要注意我们需要从右往左遍历单调栈,因为要保证最先找到的左端点一定是在右端点左边的。用一个变量 cnt 统计需要删除的元素个数,最终计算答案得到结果。 时间复杂度:O(n),两次单调栈遍历,最差情况下遍历整个数组。空间复杂度:O(n),单调栈的元素个数最大为 n。 代码:

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值