/*class ListNode {
* val: number
* next: ListNode | null
* constructor(val?: number, next?: ListNode | null) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
* }
*/
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* @param pHead1 ListNode类
* @param pHead2 ListNode类
* @return ListNode类
*/
/**
* 解法一:迭代
* 思路:
* (1)新建一个空的表头后面连接两个链表排序后的结点。
* (2)遍历两个链表都不为空的情况,取较小值添加在新的链表后面,每次只把被添加的链表的指针后移。
* (3)遍历到最后肯定有一个链表还有剩余的结点,它们的值将大于前面所有的,直接连在新的链表后面即可。
* 时间复杂度: O(n),最坏情况遍历2 * n个结点
* 空间复杂度: 0(1),无额外空间使用,新建的链表属于返回必要空间
*/
export function Merge(pHead1: ListNode, pHead2: ListNode): ListNode {
if (pHead1 == null) return pHead2
if (pHead2 == null) return pHead1
let head: ListNode = new ListNode()// 加一个表头
let cur: ListNode = head
while (pHead1 != null && pHead2 != null) {
if (pHead1.val <= pHead2.val) { // 取较小值的节点
cur.next = pHead1
pHead1 = pHead1.next // 移动取值的指针
} else {
cur.next = pHead2
pHead2 = pHead2.next
}
cur = cur.next // 指针后移
}
if (pHead1 != null) cur.next = pHead1
if (pHead2 != null) cur.next = pHead2
return head.next // 返回值去掉表头
}
/**
* 解法二:递归
* 思路:
* (1)每次比较两个链表当前结点的值,然后取较小值的链表指针往后,另一个不变送入递归中。
* (2)递归回来的结果我们要加在当前较小值的结点后面,相当于不断在较小值后面添加结点。
* (3)递归的终止是两个链表为空。
* 时间复杂度: O(n),最坏相当于遍历两个链表每个结点一次
* 空间复杂度: O(n), 递归栈长度最大为 n
*/
export function Merge(pHead1: ListNode, pHead2: ListNode): ListNode {
if (pHead1 == null) return pHead2
if (pHead2 == null) return pHead1
if (pHead1.val <= pHead2.val) { // 先用较小的值的节点
pHead1.next = Merge(pHead1.next, pHead2)
return pHead1
} else {
pHead2.next = Merge(pHead1, pHead2.next)
return pHead2
}
}
一站式解决前端面试高频算法题