简体   繁体   English

从链表中删除重复项

[英]Removing duplicates from a linked list

I have the following code but I don't understand where head is modified:我有以下代码,但我不明白head在哪里被修改:

static void removeDuplicates(Node head) {
    HashSet<Integer> set = new HashSet<>();
    Node previous = null;

    while (head != null) {
        if (set.contains(head.data)) {
            previous.next = head.next;
        } else {
            set.add(head.data);
            previous = head;
        }
        head = head.next;
    }
}

What confuses me is that head is set to null every time the function ends.令我困惑的是,每次 function 结束时, head都设置为null Why is the method still correct?为什么方法还是正确的?

head is a variable (by way of being a local parameter). head是一个变量(作为局部参数)。 Given that it is a variable of a non-primitive type, the thing it holds is a reference .鉴于它是一个非原始类型的变量,它持有的东西是一个引用 It's like a treasure map. Not like treasure.像宝藏map。不像宝藏。 You can use it to get to treasure, but it is not, itself, treasure.你可以用它来获得宝藏,但它本身并不是宝藏。

Java is strictly pass-by-value, ie, everything is a copy . Java 严格按值传递,即一切都是副本 Whatever code called removeDuplicates had a treasure map, and made a copy of this map, and handed that copy to the removeDuplicates method.无论什么代码调用removeDuplicates都有一个宝藏 map,并复制了这个 map,并将该副本交给removeDuplicates方法。

head = head.next is java-ese for: head = head.next是 java-ese 的:

  • ( head.next - the . specifically): Dot is 'dereference': Take the head treasuremap, follow it to the X, dig down, and open the treasure. head.next - 具体来说是. ):点是“取消引用”:拿走head藏宝图,跟随它到 X,向下挖掘,然后打开宝藏。 Inside, find a little tab named 'next'.在里面,找到一个名为“下一步”的小标签。 On it, you will find a treasure map (that's a treasure map, in a treasure chest).在上面,你会找到宝物 map(这是宝物 map,在宝箱中)。
  • Now the head =... part: Now take the head treasure map and erase what is there . Now the head =...部分:现在取出head宝藏 map 并擦除其中的内容 Then copy over the next map from the chest.然后从箱子里抄过来next map。 When you're done, put the next map back in the chest, close it up, and cover it back up.完成后,将next map 放回箱子,合上,再盖好。

At the end of the method, head , which is just a local treasure map, just poofs out of existence immediately, as do all local variables.在该方法的最后, head ,它只是一个本地宝藏 map,就像所有本地变量一样,立即消失。

Yeah, on the last run, head = head.next means that head is blank ( null ) - the last treasure chest you open does have a piece of paper named next that can contain a treasure map, but it is blank ( null ), and you copy this over, thus, head itself will be blank.是的,在最后一次运行中, head = head.next表示head是空白的 ( null ) - 你打开的最后一个宝箱确实有一张名为next的纸可以包含宝物 map,但它是空白的 ( null ),然后将其复制过来,因此head本身将是空白的。

This is irrelevant.这无关紧要。 head poofs out of existence entirely (the treasure map, not the treasure it leads to), given that it is a local variable and the method that created it ends, and this has absolutely no effect whatsoever on the caller, because its treasure map wasn't changed or destroyed at all - the copy it made was, so this doesn't matter. head poofs 完全不存在(宝藏 map,而不是它导致的宝藏),因为它是一个局部变量并且创建它的方法结束了,这对调用者绝对没有任何影响,因为它的宝藏 map 是根本没有改变或销毁 - 它制作的副本是,所以这无关紧要。

Make a very slight change and this becomes a different story: If instead of head being a local var, it was a field (so, replace removeDuplicates(Node head) with removeDuplicates() , and let's posit that there is a field private Node head; in whatever class this method is in), then head = head.next is wiping out the treasure map that is the field itself which obviously survives the method's execution, and will be visible by other code.做一个非常小的改变,这就变成了一个不同的故事:如果head不是本地变量,而是一个字段(因此,将removeDuplicates(Node head)替换为removeDuplicates() ,让我们假设有一个字段private Node head;无论这个方法在 class 中),然后head = head.next正在清除宝藏 map,它是显然在方法执行后幸存下来的字段本身,并且可以被其他代码看到。 Then your idea that 'hey wait a second this destroys head .'然后你的想法是'嘿,等一下,这会破坏head 。' carries water.携带水。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM