链表-删除排序链表中的重复元素

leetcode(使用的是中文网站:领扣):83

给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字。

示例 1:

输入: 1->2->3->3->4->4->5
输出: 1->2->5

示例 2:

输入: 1->1->1->2->3
输出: 2->3

一开始没有看到排序链表这个条件,所以解法有一点麻烦

解法一:

思路:再创建一个链表B,然后遍历原来的链表A,将A中的元素添加到B的链表尾部。

每次向B中添加元素时都检查一下B中是否已经存在这个元素,若存在,则不添加。代码如下:

package leetcode.LinkedList83;

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode deleteDuplicates(ListNode head) {
        if(head == null) {
            return null;
        }
        //原链表的当前节点
        ListNode cur = head.next;

        //创建一个新的链表
        ListNode newHead = new ListNode(head.val);
        ListNode newList_cur = newHead;

        while(cur!=null){
            //如果新的链表中没有这个节点,那么就添加进去
            if(!contains(newHead,cur.val)){
                newList_cur.next = new ListNode(cur.val);
                newList_cur = newList_cur.next;
            }
            cur = cur.next;
        }
        return newHead;
    }

    //检测链表中是否包含某个元素
    boolean contains(ListNode head,int val){
        while(head != null){
            if(head.val == val){
                return true;
            } else {
                head = head.next;
            }
        }
        return false;
    }
    public static void main(String[] args) {
        int arr[] = {1,2,3,4,3,5,6};
        ListNode head = new ListNode(arr);
        System.out.println(head);

        ListNode ret = (new Solution()).deleteDuplicates(head);
        System.out.println("最终结果:"+ret);
    }
}

这里为了测试代码,我们这里可以写一个将数组转化成链表的函数

本地测试用代码(后面的代码测试也是用的这个):

package leetcode.LinkedList83;

/**
 * 用于本地测试
 */
class ListNode {
  int val;
  ListNode next;
  ListNode(int x) { val = x; }

  // 链表节点的构造函数
  // 使用arr为参数,创建一个链表,当前的ListNode为链表头结点
  ListNode(int[] arr){
    if(arr == null || arr.length == 0){
      throw new IllegalArgumentException("arr can not be empty");
    }

    this.val = arr[0];
    ListNode cur = this;
    for (int i = 1; i < arr.length; i++) {
      cur.next = new ListNode(arr[i]);
      cur = cur.next;
    }
  }

  @Override
  public String toString(){
    StringBuilder sb = new StringBuilder();
    ListNode cur = this;
    while(cur != null){
      sb.append(cur.val);
      sb.append("->");
      cur = cur.next;
    }
    sb.append("NULL");
    return sb.toString();
  }
}

解法二(这里才用到题目的已经排序的条件):

思路:使用递归,在递推之后回归的过程中我们可以比较当前链表和子链的值是否相等,相等的话就直接返回子链,否则就返回当前链表。

链表的递归,可以想象成不断的把问题交给子链去解决,最后返回的时候也是不断的返回子链的结果。

package leetcode.LinkedList83;
public class Solution2 {
    public ListNode deleteDuplicates(ListNode head) {
        if(head == null || head.next == null) {
            return head;
        } else {
//            ListNode res = deleteDuplicates(head.next);
//            if(head.val == head.next.val){
//                return res;
//            } else {
//                head.next = res;
//                return head;
//            }
            head.next = deleteDuplicates(head.next);
            return head.val == head.next.val ? head.next:head;
        }
    }
    public static void main(String[] args) {
        int arr[] = {1,2,3,3,5,6};
        ListNode head = new ListNode(arr);
        System.out.println(head);

        ListNode ret = (new Solution2()).deleteDuplicates(head);
        System.out.println("最终结果:"+ret);
    }
}

简单的画个图表示一下(用res更好理解一点):

最后是官方给出的使用迭代的方法:

解法三:

思路:每一次都比较当前节点和下一个节点的值,如果不同,就将当前节点后移,如果相同,就不改变当前节点,直至下一个节点的值与当前节点的值不相等。

public ListNode deleteDuplicates(ListNode head) {
    ListNode current = head;
    while (current != null && current.next != null) {
        if (current.next.val == current.val) {
            current.next = current.next.next;
        } else {
            current = current.next;
        }
    }
    return head;
}

刚刚开始接触leetcode,许多解法都还没怎么分析复杂度,所以自己的解法也不一定是什么好的方法,大家简单看下思路就好。

错漏之处请在评论区之处。

原文地址:https://www.cnblogs.com/bax-life/p/9693635.html

时间: 2024-11-08 21:01:48

链表-删除排序链表中的重复元素的相关文章

【LeetCode-面试算法经典-Java实现】【026-Remove Duplicates from Sorted Array(删除排序数组中的重复元素)】

[026-Remove Duplicates from Sorted Array(删除排序数组中的重复元素)] [LeetCode-面试算法经典-Java实现][所有题目目录索引] 原题 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 anot

删除排序数组中的重复数字、买卖股票的最佳时机、爬楼梯

题目1:删除排序数组中的重复数字 描述:给定一个排序数组,在原数组中删除重复出现的数字,使得每个元素只出现一次,并且返回新的数组的长度. 不要使用额外的数组空间,必须在原地没有额外空间的条件下完成. 题目2:买卖股票的最佳时机 描述:假设有一个数组,它的第i个元素是一支给定的股票在第i天的价格.如果你最多只允许完成一次交易(例如,一次买卖股票),设计一个算法来找出最大利润. 题目3:爬楼梯 描述:假设你正在爬楼梯,需要n步你才能到达顶部.但每次你只能爬一步或者两步,你能有多少种不同的方法爬到楼顶

LintCode(101)删除排序数组中的重复数字 II

题目 跟进"删除重复数字": 如果可以允许出现两次重复将如何处理? 您在真实的面试中是否遇到过这个题? Yes 样例 给出数组A =[1,1,1,2,2,3],你的函数应该返回长度5,此时A=[1,1,2,2,3]. 分析 与上题思路相同,只需要增加一个记录元素出现次数的变量即可,限制最多出现2次. Python代码 class Solution: """ @param A: a list of integers @return an integer &q

LintCode(100)删除排序数组中的重复数字

题目 给定一个排序数组,在原数组中删除重复出现的数字,使得每个元素只出现一次,并且返回新的数组的长度. 不要使用额外的数组空间,必须在原地没有额外空间的条件下完成. 您在真实的面试中是否遇到过这个题? Yes 样例 给出数组A =[1,1,2],你的函数应该返回长度2,此时A=[1,2]. 分析 对排序数组去重,要求空间复杂度为O(1) 遍历一次数组,将不重复元素保留,重复元素被覆盖,最后删除末尾剩余的元素即可. Python代码 # #100 删除排序数组中的重复数字 # class Solu

Leetcode_删除排序数组中的重复项

Leetcode  删除排序数组中的重复项 题目: 给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度. 不要使用 额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成. 示例 1: 给定数组 nums = [1,1,2], 函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2. 你不需要考虑数组中超出新长度后面的元素. 示例 2: 给定 nums = [0,0,1,1,1,2,2,3,3,4]

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

26. 删除排序数组中的重复项 package com.test; import java.util.Arrays; public class Lesson026 { public static void main(String[] args) { int[] nums = {0,0,1,1,1,2,2,3,3,4}; int length = removeDuplicates(nums); System.out.println(length); } private static int rem

LeetCode:删除排序数组中的重复项||【80】

LeetCode:删除排序数组中的重复项||[80] 题目描述 给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素最多出现两次,返回移除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成. 示例 1: 给定 nums = [1,1,1,2,2,3], 函数应返回新长度 length = 5, 并且原数组的前五个元素被修改为 1, 1, 2, 2, 3 . 你不需要考虑数组中超出新长度后面的元素. 示例 2: 给定 nums =

LeetCode 第26题 删除排序数组中的重复项

/*26. 删除排序数组中的重复项 给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成. 示例 1: 给定数组 nums = [1,1,2], 函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2. 你不需要考虑数组中超出新长度后面的元素.示例 2: 给定 nums = [0,0,1,1,1,2,2,3,3,4], 函数应该返回新的

每天一道面试题--删除排序数组中的重复项 II(python实现)

删除排序数组中的重复项 II 给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素最多出现两次,返回移除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成. 示例 1: 给定 nums = [1,1,1,2,2,3], 函数应返回新长度 length = 5, 并且原数组的前五个元素被修改为 1, 1, 2, 2, 3 . 你不需要考虑数组中超出新长度后面的元素. 示例 2: 给定 nums = [0,0,1,1,1,1,2,3,

[leetcode] 26. 删除排序数组中的重复项

26. 删除排序数组中的重复项 一开始各种坐标变换把我绕晕了- -,恶心的水题 class Solution { public int removeDuplicates(int[] nums) { if (nums.length == 0) return 0; int j = 0; for (int i = 0; i < nums.length; i++) if (nums[i] != nums[j]) nums[++j] = nums[i]; return ++j; } } 原文地址:http