今天,在做一个关于Facebook JavaScript问题的模拟采访时,我忽略了如何处理单链接列表。到目前为止,我的代码只是一个函数,它接受两个链表并返回另一个链表。我的计划在下面。
问题给你两个任意长度的非空链表,代表两个非负整数。数字按相反顺序存储,每个节点包含一个数字。将这两个数字相加,并将其作为链表返回。
您可以假设这两个数字不包含任何前导零,除了数字0本身。
示例:
输入:(2-
计划
/*
* Definition for singly-linked list.
* function ListNode(val)
* {
* this.val = val;
* this.next = null;
* }
*/
/* Expected input and output.
* @param {ListNode} l1
* @param {ListNode} l2
* @return {ListNode}
*/
var addTwoNumbers = function(l1, l2)
{
};
完成计划第8步的一种方法是使用数组的减少方法。
这样地:
function ListNode(val)
{
this.val = val;
this.next = null;
}
const array2List = function(list, nextValue)
{
let node = new ListNode(parseInt(nextValue));
node.next = list;
return node;
}
let numberArray = Array.from('807');
let list = numberArray.reduce(array2List, null);
console.log(list);
或者改变你的计划,做一些类似的事情:
const addTwoNumbers = function(l1, l2)
{
let sumList = new ListNode(0);
let node = sumList;
let carry = 0;
while (node)
{
let l1Value = (l1) ? parseInt(l1.val) : 0;
let l2Value = (l2) ? parseInt(l2.val) : 0;
let sum = carry + l1Value + l2Value;
node.val = sum % 10;
carry = (sum - node.val)/10;
if (l1) { l1 = l1.next }
if (l2) { l2 = l2.next }
node.next = (l1 || l2 || carry) ? new ListNode(0) : null;
node = node.next;
}
return sumList;
}
您不必创建包含与链表相同数据的新数组。您可以在迭代这两个列表并在同一循环中创建结果列表的同时处理这两个列表。在进行此操作时,您必须注意从加法器中进行的进位。
基本上你必须这样做:
let currNodeList1 = l1, currNodeList2 = l2; //assuming that l1 and l2 point to head of linked list
let resultListHead = null, currNodeResultList = null; //to store the result
let carry = 0, sum = 0;
while(currNodeList1 != null && currNodeList2 != null) {
sum = carry + currNodeList1.val + currNodeList2.val;
carry = Math.trunc(sum / 10);
sum = sum % 10;
let newListNode = new ListNode(sum);
if(currNodeResultList == null) {
resultListHead = newListNode;
} else {
currNodeResultList.next = newListNode;
}
currNodeResultList = newListNode;
currNodeList1 = currNodeList1.next;
currNodeList2 = currNodeList2.next;
}
if(currNodeList1 == null) { //other list is longer in length
while(currNodeList2 != null) {
// calculate sum as carry + currNodeList2.val
//same carry logic and keep appending to the end of the result list
}
}
if(currNodeList2 == null) { //other list is longer in length
while(currNodeList1 != null) {
//calculate sum as carry + currNodeList2.val
//same carry logic and keep appending to the end of the result list
}
}
显然,您可以通过重构重复的部分来使代码更加模块化,但总的想法应该是这样。
在处理链表时,可以轻松地采用递归方法。它倾向于保持代码简单。要将两个链接列表添加到一起,只需执行以下操作:
这是总纲。几乎没有需要跟踪的边缘情况
10
——在这种情况下,您必须将多余的数字带到下一个求和运算中。因此,对于12
的总和,您只需保留2
并携带1
0
-这不会影响结果。如果你尝试将1
和0
相加,你会得到1
,这是正确的选择
9
和3
的列表相加,则得到2
,下一次迭代将没有更多的列表,只有1
的结转
/*
* Definition for singly-linked list.
*/
function ListNode(val)
{
this.val = val;
this.next = null;
}
/* Expected input and output.
* @param {ListNode} l1
* @param {ListNode} l2
* @return {ListNode}
*/
var addTwoNumbers = function(l1, l2)
{
return recursivelyAddLists(l1, l2, 0);
};
/*
* Recursively add two lists together producing a new list for each digit
* @param {ListNode} l1
* @param {ListNode} l2
* @param {number} carryover
* @return {ListNode}
*/
function recursivelyAddLists(l1, l2, carryover)
{
//you can also safely assume that the carryover is always present.
//But adding a default is a good practice
carryover = carryover || 0;
//if there is nothing to add, we are finished
if (l1 == null && l2 == null && carryover === 0) return null;
//provide fallback in case at least one or both lists are exhausted
l1 = l1 || new ListNode(0);
l2 = l2 || new ListNode(0);
//calculate the sum of both nodes with any potential leftover from previous sums
var sum = l1.val + l2.val + carryover;
//clamp to only single digit numbers
var newVal = sum % 10
//the amount to move add with the next nodes
var newCarryover = Math.floor(sum / 10);
//create the result node
var newList = new ListNode(newVal);
//recursively determine what the next node is
newList.next = recursivelyAddLists(l1.next, l2.next, newCarryover);
//finish
return newList
}
//use the sample data for a test
var input1 = new ListNode(2);
input1.next = new ListNode(4);
input1.next.next = new ListNode(3);
var input2 = new ListNode(5);
input2.next = new ListNode(6);
input2.next.next = new ListNode(4);
console.log(debugPrintList(addTwoNumbers(input1, input2)))
//simple function to recursively collect the content of the list to a string
function debugPrintList(list) {
if (list.next == null) return list.val;
return list.val + " -> " + debugPrintList(list.next);
}
本文向大家介绍单链表反转 遍历法Java实现相关面试题,主要包含被问及单链表反转 遍历法Java实现时的应答技巧和注意事项,需要的朋友参考一下
问题内容: Java 8具有用于日期和时间的全新API。此API中最有用的类之一是,用于保存与时区无关的date-with-time值。 为此目的,可能有数百万行代码使用遗留类。这样,在连接旧代码和新代码时,将需要在两者之间进行转换。由于似乎没有直接的方法可以完成此任务,该怎么办呢? 问题答案: 简短答案: 说明:(基于这个问题有关LocalDate) 尽管有名称,它代表时间轴上的一个瞬间,而不是
问题内容: 是否存在一种普遍接受的技术,可以有效地将JavaScript字符串转换为ArrayBuffers,反之亦然?具体来说,我希望能够将ArrayBuffer的内容写入并读回。 问题答案: 更新 -五年来,规范中现在有了新方法(请参阅下面的支持),可以使用正确的编码在字符串和类型数组之间进行转换。 TextEncoder 该代表: 该接口表示用于特定方法的编码器,即特定的字符编码,例如, ,
问题内容: 必须是O(n)并且是就地(空间复杂度为1)。下面的代码可以工作,但是有没有更简单或更完善的方法? 问题答案: 编辑以删除每次迭代的额外比较:
本文向大家介绍如何反转单链表相关面试题,主要包含被问及如何反转单链表时的应答技巧和注意事项,需要的朋友参考一下 考察点:链表
我正在为一个CS类做一些家庭作业,并且正在努力使用一个函数来反转两个给定节点之间的双链接列表。我对自己做错了什么感到困惑,我在谷歌上搜索过,但找不到任何有帮助的东西。 我有一个双链表,我基本上使用这个函数作为辅助函数,在两个节点之间反转它,这两个节点作为函数的参数。 下面是模板的代码,有注释以便您了解我的思考过程 那么,有什么想法吗?我已经知道问题发生在哪里,是什么,但是我还不知道为什么会发生,以