去掉有序数组中重复数字 原地 leetcode java (最简单的方法)

本文介绍了一种利用荷兰国旗思路去除数组中重复元素的方法,并通过两个示例展示如何在原地操作数组,仅使用常量内存实现。包括基本算法和进阶版处理最多允许两次重复的场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.利用荷兰国旗的思路,每次记住最后一个位置,遇到一个不重复的数,放在它后面,代码很简单。

Given a sorted array, remove the duplicates in place such that each element appear only once and return the new length.

Do not allocate extra space for another array, you must do this in place with constant memory.

For example,
Given input array A = [1,1,2],

Your function should return length = 2, and A is now [1,2].

 1 public class Solution {
 2     public int removeDuplicates(int[] A) {
 3         int len=A.length;
 4         if(len==0) return 0;
 5         int pos=0;
 6         
 7         
 8         for(int i=1;i<len;i++)
 9         {
10             if(A[i]!=A[pos])
11             {
12                 pos++;
13                 A[pos]=A[i];
14                 
15                 
16             }
17             
18             
19         }
20         return pos+1;
21         
22         
23         
24     }
25         
26 }
View Code

 2.只要跟end的前一个比较就行了,思路跟上边,就一点不一样,原创啊

Follow up for "Remove Duplicates":
What if duplicates are allowed at most twice?

For example,
Given sorted array A = [1,1,1,2,2,3],

Your function should return length = 5, and A is now [1,1,2,2,3].

 1 public class Solution {
 2     public int removeDuplicates(int[] A) {
 3        int len=A.length;
 4         if(len==0) return 0;
 5         if(len==1) return 1;
 6         int end=1;
 7         for(int i=2;i<len;i++)
 8         {
 9             if(A[i]!=A[end-1])
10             {
11                 end++;
12                 A[end]=A[i];
13                 
14                 
15             }
16             
17         }
18         
19         return end+1;
20         
21     }
22 }

 

 

 

 

转载于:https://www.cnblogs.com/hansongjiang/p/3834488.html

<think>好的,我需要帮助用户找到用Java实现LeetCode第26题“删除有序数组中的重复项”的解决方案。首先,我得先理解题目要求。题目说给定一个按非递减顺序排列的数组,需要原地删除重复的元素,使得每个元素只出现一次,并返回新数组的长度。同时,必须使用O(1)的额外空间,也就是不能使用额外的数组结构,只能在原数组上修改。 接下来,我应该回顾用户提供的参考内容。用户引用了几个相关的解决方案,其中引用[5]提到了快慢指针的方法。Python示例中使用了快慢指针,i从0开始,j从1开始,当nums[j]不等于nums[i]时,i移动并保存nums[j]的值。这应该是一个双指针的典型解法,应该可以应用到Java中。 用户现在需要的是Java版本的解法,所以需要将Python或C++的代码转换成Java。在引用[5]的示例中,Java代码的结构大致是:检查数组是否为空,初始化i=0,然后循环j从1到数组末尾,如果nums[j]不等于nums[i],则i自增,并将nums[j]赋值给nums[i]。最后返回i+1作为新长度。 我需要确保Java代码的正确性。首先,处理边界情况,比如数组长度为0的情况,应该返回0。但根据题目约束,数组长度至少为1,所以可能不需要处理。不过为了代码的健壮性,可以保留检查。 然后,循环部分,用for循环遍历数组,快指针j从1开始,慢指针i从0开始。每次比较nums[j]和nums[i],如果不相等,就将i加1,并复制nums[j]到nums[i]的位置。这样,i始终指向最后一个不重复的元素,而j不断寻找下一个不同的元素。 需要注意的是,题目要求原地修改数组,所以直接操作原数组即可。此外,返回的长度是i+1,因为i是索引,从0开始,所以元素个数是索引加1。 现在,把这些逻辑用Java代码写出来。例如: public int removeDuplicates(int[] nums) { if (nums.length == 0) return 0; int i = 0; for (int j = 1; j < nums.length; j++) { if (nums[j] != nums[i]) { i++; nums[i] = nums[j]; } } return i + 1; } 这样应该就可以解决问题了。同时,需要解释代码的步骤,比如初始化两个指针,遍历数组,更新慢指针的位置,并覆盖重复项。这样用户能理解每一步的作用。 可能还需要分析时间和空间复杂度。时间复杂度是O(n),因为只遍历一次数组。空间复杂度是O(1),只用了常数级的额外变量。 最后,生成相关问题,比如时间复杂度的分析,或者如果允许最多重复两次的情况如何处理(例如LeetCode第80题),或者其他相关的双指针问题。 总结来说,我需要将已有的解决方案转换为Java,并确保正确性和符合题目的要求,同时给出清晰的解释和相关的问题。</think>### Java实现LeetCode第26题'删除有序数组中的重复项' #### 题目要求 给定一个按**非递减顺序排列**的整数数组 `nums`,需要**原地删除重复元素**,使得每个元素只出现一次,并返回新数组的长度。要求使用 $O(1)$ 的额外空间复杂度[^3]。 #### 实现思路 使用**双指针法(快慢指针)**: 1. **慢指针 `i`**:指向当前唯一元素的最后一个位置。 2. **快指针 `j`**:遍历数组,寻找下一个 `nums[i]` 不同的元素。 3. 当 `nums[j] != nums[i]` 时,将 `nums[j]` 赋值给 `nums[i+1]`,并移动 `i`。 #### 代码实现 ```java public int removeDuplicates(int[] nums) { if (nums.length == 0) return 0; int i = 0; for (int j = 1; j < nums.length; j++) { if (nums[j] != nums[i]) { i++; nums[i] = nums[j]; } } return i + 1; } ``` #### 代码解释 1. **边界处理**:若数组为空,直接返回0(题目约束数组长度至少为1,此判断可省略)。 2. **初始化指针**:`i=0` 作为慢指针,`j=1` 作为快指针。 3. **遍历数组**: - 当 `nums[j]` `nums[i]` 不同时,说明找到新唯一元素,将 `i` 后移一位,并更新 `nums[i]`。 4. **返回结果**:`i+1` 即为新数组的长度。 #### 复杂度分析 - **时间复杂度**:$O(n)$,遍历一次数组。 - **空间复杂度**:$O(1)$,仅使用常数级额外变量[^5]。 #### 示例说明 输入:`nums = [1,1,2]` 执行过程: 1. `i=0`, `j=1`:`nums[1]=nums[0]`,跳过。 2. `j=2`:`nums[2]=2 != nums[0]=1`,`i` 移动到1,`nums[1]=2`。 3. 最终数组前 `i+1=2` 个元素为 `[1,2]`,返回长度2。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值