2022.4.3题解 排序奇升偶降链表 + 两数相加Ⅱ

212 阅读1分钟

字节面试题:排序奇升偶降链表

题目描述

原始链表奇升偶降,即奇数位递增,偶数位递减。比如1 - 4 - 3 - 2 - 5。现在要将其变为递增序列:1 - 2 - 3 - 4 - 5

思路

将其拆分为两个链表:奇数位链表 1 - 3 - 5 和 偶数位链表 4 - 2

然后将偶数位链表反转为 2 - 4

再将1 - 3 - 5和2 - 4 合并为1 - 2 - 3 - 4 - 5

代码

func oddEven(head *ListNode) *ListNode {
    // 如果节点个数小于等于1,那么可以直接返回
	if head == nil || head.Next == nil{
		return head
	}

	oddHead := head
	evenHead := head.Next
	oddCur := oddHead
	evenCur := evenHead
	odummy := &ListNode{Next: oddHead}
	edummy := &ListNode{Next: evenHead}
    
    // 1. 将链表拆分
	for evenCur.Next != nil && oddCur.Next != nil {
		oddCur.Next = evenCur.Next
		oddCur = oddCur.Next
		if oddCur != nil {
			evenCur.Next = oddCur.Next
			evenCur = evenCur.Next
			if evenCur == nil {
				break
			}
		}
	}

	// 2. 反转偶数位链表
	pre := edummy
	next := &ListNode{}
	cur := evenHead
	for next != nil {
		next = cur.Next
		cur.Next = pre
		pre = cur
		cur = next
	}
	edummy.Next.Next = nil

    // 3. 合并链表
	eHeadCur := pre
	oHeadCur := odummy.Next
	dummy := &ListNode{}
	ccur := dummy
	for eHeadCur != nil || oHeadCur != nil {
		if eHeadCur == nil {
			ccur.Next = oHeadCur
			oHeadCur = oHeadCur.Next
		} else if oHeadCur == nil {
			ccur.Next = eHeadCur
			eHeadCur = eHeadCur.Next
		} else {
			if eHeadCur.Val < oHeadCur.Val {
				ccur.Next = eHeadCur
				eHeadCur = eHeadCur.Next
			} else {
				ccur.Next = oHeadCur
				oHeadCur = oHeadCur.Next
			}
		}
		ccur = ccur.Next
	}

	return dummy.Next
}

lc.445 两数相加2

题目描述

两个非空链表代表两个非负整数。链表开始即为最高位,返回代表相加结果的链表。

思路

两数相加需要从最低位开始加。由于链表的遍历方向固定,也不能随机遍历。由于题目要求不用反转链表,因此可以采用栈来存储数。

将两个链表入栈s1,s2。再依次取栈顶元素相加,将相加结果打包为节点链起来。

代码

/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode {
    s1 := make([]int,0)
    s2 := make([]int,0)
    cur1 := l1
    cur2 := l2
    
    // 1. 入栈
    for cur1!=nil{
        s1 = append(s1,cur1.Val)
        cur1 = cur1.Next
    }
    for cur2!=nil{
        s2 = append(s2,cur2.Val)
        cur2 = cur2.Next
    }
    
    // 2. 依次相加,注意最后可能会多一位
    carry := 0
    var ans *ListNode
    for len(s1)>0||len(s2)>0||carry>0{
        var c1,c2,cur int
        if len(s1)>0{
            c1 = s1[len(s1)-1]
            s1 = s1[:len(s1)-1]
        }
        if len(s2)>0{
            c2 = s2[len(s2)-1]
            s2 = s2[:len(s2)-1]
        }
        sum := c1+c2+carry
        cur = sum%10
        carry = sum/10
        tmp := &ListNode{Val:cur,Next:ans}
        
        // 用ans节点来代表链表头
        ans = tmp
    }

    return ans
}