无法在Java中分配LinkedList头节点以供将来参考
我正在尝试一个标准的面试问题,就是以LinkedList的形式添加两位数字,然后返回添加的答案。问题是: 给您两个链表,表示两个非负数。 数字按相反顺序存储,每个节点都包含 一位数。将这两个数字相加,并将其作为链表返回 输入:(2->4->3)+(5->6->4)输出:7->0->8无法在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
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的起始节点。我不明白的是
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
。你已经到了。您只需要在以后的迭代中这样做。以下是被接受的正确代码: