无法在Java中分配LinkedList头节点以供将来参考

无法在Java中分配LinkedList头节点以供将来参考,java,linked-list,pass-by-reference,Java,Linked List,Pass By Reference,我正在尝试一个标准的面试问题,就是以LinkedList的形式添加两位数字,然后返回添加的答案。问题是: 给您两个链表,表示两个非负数。 数字按相反顺序存储,每个节点都包含 一位数。将这两个数字相加,并将其作为链表返回 输入:(2->4->3)+(5->6->4)输出:7->0->8 342 + 465 = 807 Make sure there are no trailing zeros in the output list So, 7 -> 0 -> 8 -> 0 is n

我正在尝试一个标准的面试问题,就是以LinkedList的形式添加两位数字,然后返回添加的答案。问题是:

给您两个链表,表示两个非负数。 数字按相反顺序存储,每个节点都包含 一位数。将这两个数字相加,并将其作为链表返回

输入:(2->4->3)+(5->6->4)输出:7->0->8

342 + 465 = 807 Make sure there are no trailing zeros in the output list So, 7 -> 0 -> 8 -> 0 is not a valid response even though
这个值仍然是807

现在,我正在编写的代码以
ListNode
datatypes的形式接受了两个参数,这是LinkedList的起始节点。我不明白的是

  • 如何维护列表的head节点以供以后参考

  • Java中按值调用和按引用调用是如何工作的?我已经处理了指针和C++中的引用,但我现在已经尝试java中的东西了,它有很大的不同。

    class ListNode {
        public int val;
        public ListNode next;
        ListNode(int x) {
            val = x;
            next = null;
        }
    }
    
    
    public class Solution {
    
        public ListNode reverse(ListNode head) {
            ListNode curr = head;
            ListNode next = null;
            ListNode prev = null;
            while (curr != null) {
                next = curr.next;
                curr.next = prev;
                prev = curr;
                curr = next;
            }
            head = prev;
            return head;
        }
    
    
        public ListNode addTwoNumbers(ListNode a, ListNode b) {
            ListNode node = null;
            ListNode head = null;
            boolean carry = false;
            while (a != null || b != null) {
                int f = 0, s = 0;
                if (carry) {
                    f++;
                }
                carry = false;
                if (a != null) {
                    f += a.val;
                    a = a.next;
                }
                if (b != null) {
                    s = b.val;
                    b = b.next;
                }
                if (f + s > 9) {
                    carry = true;
                }
                int curr = (f + s) % 10;
                node = new ListNode(curr);
                if (head == null) {
                    head = node;
                }
                node = node.next; //warning that 'value of node assigned is never used'
            }
            if (carry) {
                node = new ListNode(1);
            }
            printList(head);
            return node;
        }
    }
    

  • 节点
    的作用不明确

            node = new ListNode(curr);
            node = node.next; // assigns null
    
    节点重命名为
    previous
    并执行以下操作:

            int curr = (f + s) % 10;
            ListNode newNode = new ListNode(curr);
            if (head == null) { // Or `previous == null`
                head = newNode;
            } else {
                previous.next = newNode;
            }
            previous = newNode;
    
        ...
        return head;
    
    处理
    head
    的技术是使其成为容器类
    LinkedList
    的私有字段

    在java中,参数传递是按值调用的:
    f(a)
    从不更改变量
    a
    :存储对象指针/值的插槽。而是将指向对象的指针/值推送到堆栈上。(对象值的字段可能已更改。)

    因此递归插入可能看起来像
    head=insert(head,…)

    在C中,on可以使用别名,而不仅仅用于参数传递:

    ListNode* head = NULL;
    ListNode** node = &head;
    shile (...) {
        ...
        *node = newNode;
        node = &(newNode->next);
    }
    
    为什么这么复杂

    public class Solution {
    
        public ListNode addTwoNumbers(ListNode a, ListNode b) {
            int firstNumber = nodeToNumber(a);
            int secondNumber = nodeToNumber(b);
            return numberToNode(firstNumber + secondNumber);
        }
    
        public int nodeToNumber(ListNode node) {
            if (node.next != null) return node.value + 10 * nodeToNumber(node.next);
            return node.value;
        }
    
        public ListNode numberToNode(int number) {
            ListNode result = new ListNode(number % 10);
            if (number > 10) result.next = numberToNode(number / 10);
            return result;
        }
    }
    

    “Java中按值调用和按引用调用是如何工作的”Java总是这样。但在此上下文中“值”的含义令人困惑:传递的变量的值,可能是引用。因此,虽然引用的对象不是通过值传递的,但引用该对象的变量是;这意味着你不能像在C++中那样用一种单独的方法交换值,比如说,“安迪特纳”,用java来处理链接问题的最好方法是什么?维护head和其他值非常痛苦,因为在Java中,如果我简单地执行
    head=node
    ,则head的值会根据node发生变化,最终无法检索head值。如何避免这种情况?
    处理head的技术是将其作为容器类LinkedList的私有字段
    这正是我们的想法。前面的方法似乎是解决这个问题的好方法,谢谢你的回答让我失望。如果我在每个阶段打印
    head
    和previous的值,我会得到相同的答案。看看这里的代码:请编辑您的答案。它将是'int curr=(f+s)%10;ListNode newNode=新ListNode(curr);if(previous==null){previous=newNode;head=newNode;}else{previous.next=newNode;previous=previous.next;}`我看到了
    previous=previous.next
    ,它将null赋值给previous,但在循环的末尾,一个将previous设置为newNode。然后一切都应该工作。在开始时,当previous为null并且您正在分配它
    newNode
    ,您不需要执行
    previous=previous.next
    。你已经到了。您只需要在以后的迭代中这样做。以下是被接受的正确代码: