我对 LeetCode 问题的解决方案运行良好,直到我尝试使用辅助函数来改进它。参数没有被返回

My solution to a LeetCode problem works fine, until I try to improve it by using a helper function. The argument isn't being returned

您好,在此先感谢您的帮助!

所以我在尝试解决 LeetCode 问题时似乎在实现辅助函数时遇到了问题。我已经找到了一个有效的解决方案,但是当我尝试将重复的逻辑包装在辅助函数中时,似乎参数没有被 returned.

问题是合并两个已排序的 linked 列表并将其 return 作为一个新的已排序列表。新列表应该通过将前两个列表的节点拼接在一起来制作。这是 LC 问题的 link:https://leetcode.com/problems/merge-two-sorted-lists/

这是我的工作解决方案:

var mergeTwoLists = function(l1, l2) {
    let dummyHead = new ListNode(0),
        q = l1,
        v = l2,
        curr = dummyHead;
    while (q !== null || v !== null) {
        if (q && v) {
            if ( q.val !== null && v.val !== null) {
                if (q.val <= v.val) {
                    curr.next = new ListNode(q.val);
                    curr = curr.next;
                    q = q.next;        
                } else {
                    curr.next = new ListNode(v.val);
                    curr = curr.next;
                    v = v.next;
                }
            } else if (q.val !== null) {
                curr.next = new ListNode(q.val);
                curr = curr.next;
                q = q.next;
            } else {
                curr.next = new ListNode(v.val);
                curr = curr.next;
                v = v.next;
            }
        } else if (q) {
            curr.next = new ListNode(q.val);
            curr = curr.next;
            q = q.next;
        } else {
            curr.next = new ListNode(v.val);
            curr = curr.next;
            v = v.next;
        }      
    }
    return dummyHead.next;
};

如您所见,在我的整个解决方案中,同一步骤重复了多次。一旦我尝试使用辅助函数处理它,似乎参数 curr 被 returned 存在问题。每次函数被算法 运行 时,它总是显得新鲜。

我确定我遗漏了一些明显的东西。任何帮助将不胜感激:)这是使用辅助函数实现的解决方案:

var mergeTwoLists = function(l1, l2) {
    let dummyHead = new ListNode(0),
        q = l1,
        v = l2,
        curr = dummyHead;
    while (q !== null || v !== null) {
        if (q && v) {
            if ( q.val !== null && v.val !== null) {
                if (q.val <= v.val) {
                    attachNode(curr, q);
                } else {
                    attachNode(curr, v);
                }
            } else if (q.val !== null) {
                attachNode(curr, q);
            } else {
                attachNode(curr, v);
            }
        } else if (q) {
            attachNode(curr, q);
        } else {
            attachNode(curr, v);
        }    
    }
    return dummyHead.next;
};

function attachNode(curr, value) {
    curr.next = new ListNode(value.val);
    curr = curr.next;
    value = value.next;
    return curr;
}

你在函数作用域上犯了一个错误。如果你有一个像

这样的函数
function f(arg) {
    arg = 'another value';
}

then arg 在调用作用域中不变。参数 arg 是调用范围中参数的副本,其值不会更改调用范围中的参数:

let arg = 'some value';
f(arg);
arg === 'some value'; // this is true

看起来您在某种程度上正在考虑这一点,因为您 return cur 来自该函数,但您没有将值分配给任何东西。

  • 我们不必将 value 设置为 value.next,因为列表已经排序;

  • Linked List 中,只需跟踪链接并连接它们就足够了:

递归:

const mergeTwoLists = function(l1, l2) {
    if (l1 === null) {
        return l2;
    }

    if (l2 === null) {
        return l1;
    }

    if (l1.val < l2.val) {
        l1.next = mergeTwoLists(l1.next, l2)
        return l1;

    } else {
        l2.next = mergeTwoLists(l1, l2.next)
        return l2;
    }
}

迭代:

const mergeTwoLists = function(l1, l2) {
    const sentinel = {
        val: -1,
        next: null
    };

    let head = sentinel;
    while (l1 && l2) {
        if (l1.val > l2.val) {
            head.next = l2;
            l2 = l2.next;
        } else {
            head.next = l1;
            l1 = l1.next;
        }
        
        head = head.next;
    }

    head.next = l1 || l2;

    return sentinel.next;
}