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

时间:2016-09-30 10:49:51

标签: java linked-list pass-by-reference

我正在尝试一个标准的面试问题,即以链表的形式添加两位数字并返回添加的答案。这是一个问题:

  

您将获得两个代表两个非负数的链表。   数字以相反的顺序存储,并且每个节点都包含   一位数。添加两个数字并将其作为链接列表返回。

     

输入:(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数据类型的形式接受两个参数,这是LinkedLists的起始节点。我不理解的是

  1. 如何维护列表的头节点以便稍后引用?
  2. 如何按值调用和通过引用调用在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;
        }
    }
    

2 个答案:

答案 0 :(得分:1)

node扮演一个模棱两可的角色。

        node = new ListNode(curr);
        node = node.next; // assigns null

node重命名为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);
}

答案 1 :(得分:0)

为什么这么复杂?

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;
    }
}