Remove Duplicates from Sorted List

本文将探讨如何在给定的排序链表中移除所有重复元素,确保每个元素仅出现一次,并通过实现代码展示了解决方案。

  1. 首先我要在纸上,非常非常聪明且迅速且机灵,
  2. 给出几个用例,找出边界用例和特殊用例,确定特判条件;在编码前考虑到所有的条件
  3. 向面试官提问:问题规模,特殊用例
  4. 给出函数头
  5. 暴力解,简述,优化。
  6. 给出能够想到的最优价
  7. 伪代码,同时结合用例
  8. 真实代码

Remove Duplicates from Sorted List

Given a sorted linked list, delete all duplicates such that each element appear only once.

For example,
Given 1->1->2, return 1->2.
Given 1->1->2->3->3, return 1->2->3.



/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
ListNode* deleteDuplicates (ListNode* head)
{
    if(head==NULL || head->next==NULL) return head;
    ListNode* c = head->next;
    ListNode* p = head;
    
    while(c!=NULL) // We assume that there is no loop in the list.
    {
        ListNode* n = c->next;
        
        if(p->val == c->val)
        {
            p->next = n;
            delete c;
            c = n;
        }
        else
        {
            p = c;
            c = n;            
        }    
    }
    return head;
}
};






你的代码的目的是去除数组中重复的元素,并将去重后的元素放回原数组 `nums` 的前面,返回去重后的长度。然而,这段代码存在一些问题: --- ### ✅ 正确的逻辑应该是: 1. 遍历数组,跳过连续相同的元素。 2. 将不重复的元素保存到一个新的结构里。 3. 最后把结果写回到原数组的前部。 --- ## ❌ 存在的问题分析: ### 问题 1:`j` 被赋值为 `i + 1` 后,你没有处理越界情况 ```java int j = i+1; if (j<=nums.length - 1&& nums[j] == nums[i]){ ``` 虽然你在判断 `j <= nums.length - 1`,但后续的 while 循环没有再次检查边界: ```java while (nums[j] == nums[i]){ j++; } ``` 当 `j` 超出数组范围时会抛出 `ArrayIndexOutOfBoundsException`。 --- ### 问题 2:`i = j;` 导致跳过了一个元素 例如数组是 `[1,1,1]`,当你在 `i=0`,进入 `while` 循环后 `j` 增加到了 3(超出数组),然后你执行了 `i = j`,此时 `i = 3`,循环结束。实际上你应该只保留第一个 `1`,其余跳过,但你并没有正确地控制这个过程。 --- ### 问题 3:`sorted.add(nums[i]);` 在某些情况下会重复添加元素 --- ## ✅ 正确的 Java 实现(使用双指针法) 下面是一个更高效、简洁、标准的实现方式: ```java class Solution { 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; // 返回新数组的长度 } } ``` --- ### 🔍 代码解释: - 使用两个指针 `i` 和 `j`: - `j` 是快指针,用来遍历整个数组; - `i` 是慢指针,指向当前不重复部分的最后一个位置。 - 当发现 `nums[j] != nums[i]` 时,说明遇到了新的不重复元素: - 先让 `i++`,腾出位置; - 然后把 `nums[j]` 的值复制过来。 - 最终 `[0...i]` 就是去重后的数组内容,长度为 `i+1`。 --- ### 🧪 示例输入输出: 输入: ```java int[] nums = {0,0,1,1,1,2,2,3,3,4}; ``` 输出: ```java // 修改后的 nums 前5位为 [0,1,2,3,4] // 返回值为 5 ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值