![](/img/trans.png)
[英]How this Java code works? Remove duplicates from an unsorted linked list
[英]Remove duplicates from an unsorted linked list
import java.util.*;
/*
* Remove duplicates from an unsorted linked list
*/
public class LinkedListNode {
public int data;
public LinkedListNode next;
public LinkedListNode(int data) {
this.data = data;
}
}
public class Task {
public static void deleteDups(LinkedListNode head){
Hashtable<Integer, Boolean> table=new Hashtable<Integer, Boolean>();
LinkedListNode previous=null;
//nth node is not null
while(head!=null){
//have duplicate
if(table.containsKey(head.data)){
//skip duplicate
previous.next=head.next;
}else{
//put the element into hashtable
table.put(head.data,true);
//move to the next element
previous=head;
}
//iterate
head=head.next;
}
}
public static void main (String args[]){
LinkedList<Integer> list=new LinkedList<Integer>();
list.addLast(1);
list.addLast(2);
list.addLast(3);
list.addLast(3);
list.addLast(3);
list.addLast(4);
list.addLast(4);
System.out.println(list);
LinkedListNode head=new LinkedListNode(list.getFirst());
Task.deleteDups(head);
System.out.println(list);
}
}
结果: [1, 2, 3, 3, 3, 4, 4] [1, 2, 3, 3, 3, 4, 4]
它不会消除重复项。
为什么方法不起作用?
遍历链表,将每个元素添加到哈希表中。 当我们发现重复元素时,我们删除该元素并继续迭代。 由于我们使用的是链表,因此我们可以一次性完成所有这些操作。
下面的解决方案需要 O(n) 时间,n 是链表中元素的数量。
public static void deleteDups (LinkedListNode n){
Hashtable table = new Hashtable();
LinkedListNode previous = null;
while(n!=null){
if(table.containsKey(n.data)){
previous.next = n.next;
} else {
table.put(n.data, true);
previous = n;
}
n = n.next;
}
}
下面的代码运行在 O(1) 空间但 O(N 平方) 时间。
public void deleteDups(LinkedListNode head){
if(head == null) return; LinkedListNode currentNode = head; while(currentNode!=null){ LinkedListNode runner = currentNode; while(runner.next!=null){ if(runner.next.data == currentNode.data) runner.next = runner.next.next; else runner = runner.next; } currentNode = currentNode.next; }
}
参考 : Gayle laakmann mcdowell
这是在java中执行此操作的两种方法。 上面使用的方法在 O(n) 中有效,但需要额外的空间。 第二个版本在 O(n^2) 中运行但不需要额外的空间。
import java.util.Hashtable;
public class LinkedList {
LinkedListNode head;
public static void main(String args[]){
LinkedList list = new LinkedList();
list.addNode(1);
list.addNode(1);
list.addNode(1);
list.addNode(2);
list.addNode(3);
list.addNode(2);
list.print();
list.deleteDupsNoStorage(list.head);
System.out.println();
list.print();
}
public void print(){
LinkedListNode n = head;
while(n!=null){
System.out.print(n.data +" ");
n = n.next;
}
}
public void deleteDups(LinkedListNode n){
Hashtable<Integer, Boolean> table = new Hashtable<Integer, Boolean>();
LinkedListNode prev = null;
while(n !=null){
if(table.containsKey(new Integer(n.data))){
prev.next = n.next; //skip the previously stored references next node
}else{
table.put(new Integer(n.data) , true);
prev = n; //stores a reference to n
}
n = n.next;
}
}
public void deleteDupsNoStorage(LinkedListNode n){
LinkedListNode current = n;
while(current!=null){
LinkedListNode runner = current;
while(runner.next!=null){
if(runner.next.data == current.data){
runner.next = runner.next.next;
}else{
runner = runner.next;
}
}
current = current.next;
}
}
public void addNode(int d){
LinkedListNode n = new LinkedListNode(d);
if(this.head==null){
this.head = n;
}else{
n.next = head;
head = n;
}
}
private class LinkedListNode{
LinkedListNode next;
int data;
public LinkedListNode(int d){
this.data = d;
}
}
}
您可以使用以下 java 方法删除重复项:
1) complexity
为O(n^2)
public void removeDuplicate(Node head) {
Node temp = head;
Node duplicate = null; //will point to duplicate node
Node prev = null; //prev node to duplicate node
while (temp != null) { //iterate through all nodes
Node curr = temp;
while (curr != null) { //compare each one by one
/*in case of duplicate skip the node by using prev node*/
if (curr.getData() == temp.getData() && temp != curr) {
duplicate = curr;
prev.setNext(duplicate.getNext());
}
prev = curr;
curr = curr.getNext();
}
temp = temp.getNext();
}
}
输入:1=>2=>3=>5=>5=>1=>3=>
输出:1=>2=>3=>5=>
2 ) 使用哈希表的complexity
为O(n) 。
public void removeDuplicateUsingMap(Node head) {
Node temp = head;
Map<Integer, Boolean> hash_map = new HashMap<Integer, Boolean>(); //create a hash map
while (temp != null) {
if (hash_map.get(temp.getData()) == null) { //if key is not set then set is false
hash_map.put(temp.getData(), false);
} else { //if key is already there,then delete the node
deleteNode(temp,head);
}
temp = temp.getNext();
}
}
public void deleteNode(Node n, Node start) {
Node temp = start;
if (n == start) {
start = null;
} else {
while (temp.getNext() != n) {
temp = temp.getNext();
}
temp.setNext(n.getNext());
}
}
输入:1=>2=>3=>5=>5=>1=>3=>
输出:1=>2=>3=>5=>
Ans 在 C 中。 首先在 nlog 时间内对链接列表 sort() 进行排序,然后删除重复的 del_dip() 。
node * partition(node *start)
{
node *l1=start;
node *temp1=NULL;
node *temp2=NULL;
if(start->next==NULL)
return start;
node * l2=f_b_split(start);
if(l1->next!=NULL)
temp1=partition(l1);
if(l2->next!=NULL)
temp2=partition(l2);
if(temp1==NULL || temp2==NULL)
{
if(temp1==NULL && temp2==NULL)
temp1=s_m(l1,l2);
else if(temp1==NULL)
temp1=s_m(l1,temp2);
else if(temp2==NULL)
temp1=s_m(temp1,l2);
}
else
temp1=s_m(temp1,temp2);
return temp1;
}
node * sort(node * start)
{
node * temp=partition(start);
return temp;
}
void del_dup(node * start)
{
node * temp;
start=sort(start);
while(start!=NULL)
{
if(start->next!=NULL && start->data==start->next->data )
{
temp=start->next;
start->next=start->next->next;
free(temp);
continue;
}
start=start->next;
}
}
void main()
{
del_dup(list1);
print(list1);
}
试试这个它可以从你的链接列表中删除重复的元素
package com.loknath.lab;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Set;
public class Task {
public static void main(String[] args) {
LinkedList<Integer> list = new LinkedList<Integer>();
list.addLast(1);
list.addLast(2);
list.addLast(3);
list.addLast(3);
list.addLast(3);
list.addLast(4);
list.addLast(4);
deleteDups(list);
System.out.println(list);
}
public static void deleteDups(LinkedList<Integer> list) {
Set s = new HashSet<Integer>();
s.addAll(list);
list.clear();
list.addAll(s);
}
}
这是一个非常简单的版本。
LinkedList<Integer> a = new LinkedList<Integer>(){{
add(1);
add(1);
}}
Set<Integer> set = new HashSet<Integer>(a);
a = new LinkedList<Integer>(set);
非常简洁。 不是吗?
I think you can just use one iterator current to finish this problem
public void compress(){
ListNode current = front;
HashSet<Integer> set = new HashSet<Integer>();
set.add(current.data);
while(current.next != null){
if(set.contains(current.next.data)){
current.next = current.next.next; }
else{
set.add(current.next.data);
current = current.next;
}
}
}
第一个问题是
LinkedListNode head=new LinkedListNode(list.getFirst());
实际上并不使用list
的内容初始化head
。 list.getFirst()
只返回整数1
, head
包含1
作为其唯一元素。 您必须通过循环遍历list
来初始化head
以获取所有元素。
此外,虽然
Task.deleteDups(head)
修改head
,这使list
完全不变——没有理由将head
的更改传播到list
。 因此,要检查您的方法,您必须循环打印head
并打印出每个元素,而不是再次打印出list
。
试试这个。它的工作。 // 去除链表中的重复项
import java.io.*;
import java.util.*;
import java.text.*;
class LinkedListNode{
int data;
LinkedListNode next=null;
public LinkedListNode(int d){
data=d;
}
void appendToTail(int d){
LinkedListNode newnode = new LinkedListNode(d);
LinkedListNode n=this;
while(n.next!=null){
n=n.next;
}
n.next=newnode;
}
void print(){
LinkedListNode n=this;
System.out.print("Linked List: ");
while(n.next!=null){
System.out.print(n.data+" -> ");
n=n.next;
}
System.out.println(n.data);
}
}
class LinkedList2_0
{
public static void deletenode2(LinkedListNode head,int d){
LinkedListNode n=head;
// If It's head node
if(n.data==d){
head=n.next;
}
//If its other
while(n.next!=null){
if(n.next.data==d){
n.next=n.next.next;
}
n=n.next;
}
}
public static void removeDuplicateWithBuffer(LinkedListNode head){
LinkedListNode n=head;
LinkedListNode prev=null;
Hashtable<Integer, Boolean> table = new Hashtable<Integer, Boolean>();
while(n!=null){
if(table.containsKey(n.data)){
prev.next=n.next;
}
else{
table.put(n.data,true);
prev=n;
}
n=n.next;
}
}
public static void removeDuplicateWithoutBuffer(LinkedListNode head){
LinkedListNode currentNode=head;
while(currentNode!=null){
LinkedListNode runner=currentNode;
while(runner.next!=null){
if(runner.next.data==currentNode.data){
runner.next=runner.next.next;
}
else
runner=runner.next;
}
currentNode=currentNode.next;
}
}
public static void main(String[] args) throws java.lang.Exception {
LinkedListNode head=new LinkedListNode(1);
head.appendToTail(1);
head.appendToTail(3);
head.appendToTail(2);
head.appendToTail(3);
head.appendToTail(4);
head.appendToTail(5);
head.print();
System.out.print("After Delete: ");
deletenode2(head,4);
head.print();
//System.out.print("After Removing Duplicates(with buffer): ");
//removeDuplicateWithBuffer(head);
//head.print();
System.out.print("After Removing Duplicates(Without buffer): ");
removeDuplicateWithoutBuffer(head);
head.print();
}
}
这里有一些其他解决方案(与 Cracking coding inerview 略有不同,更易于阅读 IMO)。
public void deleteDupes(Node head) {
Node current = head;
while (current != null) {
Node next = current.next;
while (next != null) {
if (current.data == next.data) {
current.next = next.next;
break;
}
next = next.next;
}
current = current.next;
}
}
public void deleteDupes(Node head) {
Node current = head;
while (current != null) {
Node next = current.next;
while (next != null) {
if (current.data == next.data) {
current.next = next.next;
current = current.next;
next = current.next;
} else {
next = next.next;
}
}
current = current.next;
}
}
/**
*
* Remove duplicates from an unsorted linked list.
*/
public class RemoveDuplicates {
public static void main(String[] args) {
LinkedList<String> list = new LinkedList<String>();
list.add("Apple");
list.add("Grape");
list.add("Apple");
HashSet<String> set = removeDuplicatesFromList(list);
System.out.println("Removed duplicates" + set);
}
public static HashSet<String> removeDuplicatesFromList(LinkedList<String> list){
HashSet<String> set = new LinkedHashSet<String>();
set.addAll(list);
return set;
}
}
这是没有 HashSet 或创建节点的简单方法。
public String removeDuplicates(String str) {
LinkedList<Character> chars = new LinkedList<Character>();
for(Character c: str.toCharArray()){
chars.add(c);
}
for (int i = 0; i < chars.size(); i++){
for (int j = i+1; j < chars.size(); j++){
if(chars.get(j) == chars.get(i)){
chars.remove(j);
j--;
}
}
}
return new String(chars.toString());
}
并验证它:
@Test
public void verifyThatNoDuplicatesInLinkedList(){
CodeDataStructures dataStructures = new CodeDataStructures();
assertEquals("abcdefghjk", dataStructures.removeDuplicates("abcdefgabcdeaaaaaaaaafabcdeabcdefgabcdbbbbbbefabcdefghjkabcdefghjkghjkhjkabcdefghabcdefghjkjfghjkabcdefghjkghjkhjkabcdefghabcdefghjkj")
.replace(",", "")
.replace("]", "")
.replace("[", "")
.replace(" ", ""));
}
LinkedList<Node> list = new LinkedList<Node>();
for(int i=0; i<list.size(); i++){
for(int j=0; j<list.size(); j++){
if(list.get(i).data == list.get(j).data && i!=j){
if(i<j){
list.remove(j);
if(list.get(j)!= null){
list.get(j-1).next = list.get(j);
}else{
list.get(j-1).next = null;
}
}
else{
if(i>j){
list.remove(i);
if(list.get(i) != null){
list.get(j).next = list.get(i);
}else{
list.get(j).next = null;
}
}
}
}
}
}
下面的代码在不需要任何临时缓冲区的情况下实现了这一点。 它首先比较第一个和第二个节点,如果不匹配,则将第一个节点的字符添加到第二个节点,然后继续将第二个节点中的所有字符与第三个节点的字符进行比较,依此类推。 comperison 完成后,在离开节点之前,它会清除添加的所有内容并恢复其位于 node.val.char(0) 的旧值
F > FO > FOL >(找到匹配,node.next = node.next.next)>(再次匹配,丢弃)> FOLW > ....
public void onlyUnique(){
Node node = first;
while(node.next != null){
for(int i = 0 ; i < node.val.length(); i++){
if(node.val.charAt(i) == node.next.val.charAt(0)){
node.next = node.next.next;
}else{
if(node.next.next != null){ //no need to copy everything to the last element
node.next.val = node.next.val + node.val;
}
node.val = node.val.charAt(0)+ "";
}
}
node = node.next;
}
}
上面给出的所有解决方案看起来都经过优化,但其中大多数都将自定义Node定义为解决方案的一部分。 这是一个使用 Java 的LinkedList和HashSet的简单实用的解决方案,它不限制使用预先存在的库和方法。
时间复杂度:O(n)
空间复杂度:O(n)
@SuppressWarnings({ "unchecked", "rawtypes" })
private static LinkedList<?> removeDupsUsingHashSet(LinkedList<?> list) {
HashSet set = new HashSet<>();
for (int i = 0; i < list.size();) {
if (set.contains(list.get(i))) {
list.remove(i);
continue;
} else {
set.add(list.get(i));
i++;
}
}
return list;
}
这也保留了列表顺序。
public static void main(String[] args) {
LinkedList<Integer> linkedList = new LinkedList<>();
linkedList.add(1);
linkedList.add(2);
linkedList.add(2);
linkedList.add(3);
linkedList.add(4);
linkedList.add(5);
linkedList.add(6);
deleteElement(linkedList);
System.out.println(linkedList);
}
private static void deleteElement(LinkedList<Integer> linkedList) {
Set s = new HashSet<Integer>();
s.addAll(linkedList);
linkedList.clear();
linkedList.addAll(s);
}
这是我的 Java 版本
// Remove duplicate from a sorted linked list
public void removeDuplicates() {
Node current = head;
Node next = null;
/* Traverse list till the last node */
while (current != null) {
next = current;
/*
* Compare current node with the next node and keep on deleting them until it
* matches the current node data
*/
while (next != null && current.getValue() == next.getValue()) {
next = next.getNext();
}
/*
* Set current node next to the next different element denoted by temp
*/
current.setNext(next);
current = current.getNext();
}
}
1.完全动态方法2.从 LinkedList 中删除重复项3. LinkedList 基于动态对象的创建谢谢
import java.util.Scanner;
class Node{
int data;
Node next;
public Node(int data)
{
this.data=data;
this.next=null;
}
}
class Solution
{
public static Node insert(Node head,int data)
{
Node p=new Node(data);
if(head==null)
{
head=p;
}
else if(head.next==null)
{
head.next=p;
}
else
{
Node start=head;
while(start.next!=null)
{
start=start.next;
}
start.next=p;
return head;
//System.out.println();
}
return head;
}
public static void display(Node head)
{
Node start=head;
while(start!=null)
{
System.out.print(start.data+" ");
start=start.next;
}
}
public static Node remove_duplicates(Node head)
{
if(head==null||head.next==null)
{
return head;
}
Node prev=head;
Node p=head.next;
while(p!=null)
{
if(p.data==prev.data)
{
prev.next=p.next;
p=p.next;
}
else{
prev=p;
p=p.next;
}
}
return head;
}
public static void main(String args[])
{
Scanner sc=new Scanner(System.in);
Node head=null;
int T=sc.nextInt();
while(T-->0)
{
int ele=sc.nextInt();
head=insert(head,ele);
}
head=remove_duplicates(head);
display(head);
}
}
输入:5 1 1 2 3 3 输出:1 2 3
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.