描述
给定一个无序链表,删除其中值重复出现的节点(保留当中顺序遍历第一个出现的节点)。
示例
输入:
5 1 3 2 3 1
输出:
1 3 2
方法一:
利用哈希表,依次遍历链表节点,假设当前遍历到cur节点,如果哈希表中没有cur的值就把cur.value存进哈希表,如果哈希表内已经有值了,就直接让pre(最近一个没被删除的节点)指向cur下一个节点。
代码如下:
import java.util.Scanner;
import java.util.HashSet;
class Node{
public int value;
public Node next;
public Node(int value){
this.value=value;
}
}
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
String[] n=in.nextLine().split(" ");
String[] num=in.nextLine().split(" ");
Node node=transForNode(num);
Node nodeF=removeRep1(node);//方法1
//Node nodeF=removeRep2(node);//方法2
show(nodeF);
}
//打印链表
public static void show(Node head){
while(head!=null){
System.out.print(head.value+" ");
head=head.next;
}
System.out.println();
}
//数组转链表
public static Node transForNode(String[] nums) {
Node head = new Node(Integer.parseInt(nums[0]));
Node cur = head;
for(int i = 1; i < nums.length; i++) {
cur.next = new Node(Integer.parseInt(nums[i]));
cur = cur.next;
}
return head;
}
//方法一:哈希表法,时间复杂度O(n) 额外空间复杂度O(n)
public static Node removeRep1(Node head){
if(head==null){
return null;
}
HashSet<Integer> set=new HashSet<Integer>();
Node pre=head;
Node cur=head.next;
set.add(pre.value);
while(cur!=null){
if(set.contains(cur.value)){
pre.next=cur.next;
}else{
set.add(cur.value);
pre=cur;
}
cur=cur.next;
}
return head;
}
}
方法二:
类似选择排序,依次往后比较进行去重。时间复杂度O(n2) 额外空间复杂度O(1)
代码如下:
//方法二:类似选择排序依次遍历去重 时间复杂度O(n2) 额外空间复杂度O(1)
public static Node removeRep2(Node head){
Node cur=head;
Node pre=null;
Node next=null;
while(cur!=null){
pre=cur;
next=cur.next;
while(next!=null){
if(cur.value==next.value){
pre.next=next.next;
}else{
pre=next;
}
next=next.next;
}
cur=cur.next;
}
return head;
}