如何使用循环链表计算列表中的重复项
How to count duplicates in a list using a circular linked list
我正在努力扩展我的循环链表,我实现了一些方法来添加和删除列表中的节点。我想创建一个方法来计算列表中的重复项,该方法应该 return 列表中出现多次的对象数。
例如一个列表有 [30, 30, 50, 50, 80, 90, 10, 10] 方法应该 return:重复的数量是 3
我已经尝试实现以下方法,但此方法只计算列表中的总节点数,我应该添加什么以使其计算列表中的重复项。
public int countNode() {
int count = 0;
if (!isEmpty()) {
Node<E> temp = current;
Node<E> prev = current;
do {
if (prev.element == temp.element)
count++;
temp = temp.next;
prev = prev.next;
} while (temp != current);
}
return count;
}
您正在用同一个节点初始化 prev
和 temp
。所以比较总是 returns true 并且两个节点一起继续
简单的解决方案是使用 Java 的 HashSet
数据结构,它只允许唯一值。您需要在迭代时将每个节点的值添加到集合中。最后,集的大小和列表的大小之间的差异将是你的答案。
这里我通过将循环链表表示为整数数组来简化示例代码:
// Your linkedlist, shown as an array
int[] arr = new int[] {30, 30, 50, 50, 80, 90, 10, 10};
// Allows only unique values
HashSet<Integer> set = new HashSet<Integer>();
// Fill your set
for(int n : arr) {
set.add(n);
}
// answer = list's length - set's length
System.out.println(arr.length - set.size());
定义一个唯一的对象Node
(相对于基元)定义它的hasCode
和 equals
如下所示 mre:
import java.util.*;
public class Main {
public static void main(String[] args) {
int[] values = new int[] {30, 30, 50, 50, 80, 90, 10, 10};
Node root = null, node = null;
for(int i : values){
if(root == null) {
root= new Node(i);
}else if(node == null){
node = new Node(i);
root.setNext(node);
}else{
Node temp = new Node(i);
node.setNext(temp);
node = temp;
}
}
System.out.println("Number of distinct Nodes: "+countUniqueNodes1(root));
System.out.println("Number of distinct Nodes: "+countUniqueNodes2(root));
}
//not null safe
public static int countUniqueNodes1(Node root){
Node next = root.getNext();
Set<Node> nodesSet = new HashSet<>();
nodesSet.add(root);
while (next != null){
nodesSet.add(next);
next = next.getNext();
}
return nodesSet.size();
}
//not null safe
public static int countUniqueNodes2(Node root){
Node next = root.getNext();
List<Node> nodes = new ArrayList<>();
nodes.add(root);
while (next != null){
nodes.add(next);
next = next.getNext();
}
return (int) nodes.stream().distinct().count();
}
}
class Node{
final int value;
private Node next;
public Node(int value) {
this(value, null);
}
public Node(int value, Node next) {
this.value = value;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
@Override
public int hashCode() {
return String.valueOf(value).hashCode();
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Node)) return false;
return value == ((Node)obj).value;
}
}
我正在努力扩展我的循环链表,我实现了一些方法来添加和删除列表中的节点。我想创建一个方法来计算列表中的重复项,该方法应该 return 列表中出现多次的对象数。 例如一个列表有 [30, 30, 50, 50, 80, 90, 10, 10] 方法应该 return:重复的数量是 3
我已经尝试实现以下方法,但此方法只计算列表中的总节点数,我应该添加什么以使其计算列表中的重复项。
public int countNode() {
int count = 0;
if (!isEmpty()) {
Node<E> temp = current;
Node<E> prev = current;
do {
if (prev.element == temp.element)
count++;
temp = temp.next;
prev = prev.next;
} while (temp != current);
}
return count;
}
您正在用同一个节点初始化 prev
和 temp
。所以比较总是 returns true 并且两个节点一起继续
简单的解决方案是使用 Java 的 HashSet
数据结构,它只允许唯一值。您需要在迭代时将每个节点的值添加到集合中。最后,集的大小和列表的大小之间的差异将是你的答案。
这里我通过将循环链表表示为整数数组来简化示例代码:
// Your linkedlist, shown as an array
int[] arr = new int[] {30, 30, 50, 50, 80, 90, 10, 10};
// Allows only unique values
HashSet<Integer> set = new HashSet<Integer>();
// Fill your set
for(int n : arr) {
set.add(n);
}
// answer = list's length - set's length
System.out.println(arr.length - set.size());
定义一个唯一的对象Node
(相对于基元)定义它的hasCode
和 equals
如下所示 mre:
import java.util.*;
public class Main {
public static void main(String[] args) {
int[] values = new int[] {30, 30, 50, 50, 80, 90, 10, 10};
Node root = null, node = null;
for(int i : values){
if(root == null) {
root= new Node(i);
}else if(node == null){
node = new Node(i);
root.setNext(node);
}else{
Node temp = new Node(i);
node.setNext(temp);
node = temp;
}
}
System.out.println("Number of distinct Nodes: "+countUniqueNodes1(root));
System.out.println("Number of distinct Nodes: "+countUniqueNodes2(root));
}
//not null safe
public static int countUniqueNodes1(Node root){
Node next = root.getNext();
Set<Node> nodesSet = new HashSet<>();
nodesSet.add(root);
while (next != null){
nodesSet.add(next);
next = next.getNext();
}
return nodesSet.size();
}
//not null safe
public static int countUniqueNodes2(Node root){
Node next = root.getNext();
List<Node> nodes = new ArrayList<>();
nodes.add(root);
while (next != null){
nodes.add(next);
next = next.getNext();
}
return (int) nodes.stream().distinct().count();
}
}
class Node{
final int value;
private Node next;
public Node(int value) {
this(value, null);
}
public Node(int value, Node next) {
this.value = value;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
@Override
public int hashCode() {
return String.valueOf(value).hashCode();
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Node)) return false;
return value == ((Node)obj).value;
}
}