算法 6年前

【每日一题】合并有序链表

作者头像 刘宇帅
2904 0

题目

合并两个有序链表,合并之后仍是有序的。

分析

这个题目很简单,类似于合并排序的合并过程。

实现

节点定义

type ListNode struct {
    Val  int
    Next *ListNode
}

单元测试

var mergeOrderListList = [][][]int{
    {
        {1, 2, 3, 4},
        {7,8,9},
        {1, 2, 3, 4, 7, 8, 9},
    },{
        {1, 2, 3, 4},
        {3,8},
        {1, 2, 3, 3, 4, 8},
    },{
        {1, 2, 3, 4},
        {5},
        {1, 2, 3, 4, 5},
    },{
        {1, 2, 3, 4},
        {1},
        {1, 1, 2, 3, 4},
    },{
        {1, 3, 4},
        {2},
        {1, 2, 3, 4},
    },{
        {1, 3, 4},
        {},
        {1, 3, 4},
    },{
        {4, 10, 20},
        {1, 3},
        {1, 3, 4, 10, 20},
    },{
        {4, 10, 20},
        {5, 11, 24},
        {4, 5, 10, 11, 20, 24},
    },{
        {1, 3, 4},
        {0, 2, 4},
        {0, 1, 2, 3, 4, 4},
    },{
        {},
        {},
        {},
    },
}

func TestMergeOrderList(t *testing.T) {

    for _, items := range mergeOrderListList {
        head1 := generateList(items[0])
        head2 := generateList(items[1])

        headNew := MergeOrderList(head1, head2)

        for i := 0; i < len(items[2]); i++ {
            if headNew.Val != items[2][i] {
                t.Errorf("merger order list error %d > %d", headNew.Val, headNew.Next.Val)
            }
            headNew = headNew.Next
        }

        for headNew != nil && headNew.Next != nil {
            if headNew.Val > headNew.Next.Val {
                t.Errorf("merger order list error %d > %d", headNew.Val, headNew.Next.Val)
            }
            headNew = headNew.Next
        }

    }

}

func generateList(items []int) *ListNode {
    var head *ListNode
    cur := head
    for _, i := range items {
        temp := &ListNode{
            Val: i,
        }

        if head == nil {
            head = temp
            cur = temp
        } else {
            cur.Next = temp
            cur = temp
        }
    }

    return head
}

算法实现

func MergeOrderList(head1, head2 *ListNode) *ListNode {

    headNew := new(ListNode)
    cur := headNew

    for head1 != nil && head2 != nil  {
        for head1 != nil && head1.Val <= head2.Val  {
            cur.Next = head1
            cur = head1
            head1 = head1.Next
        }
        if head1 == nil {
            break
        }

        for head2 != nil && head2.Val <= head1.Val {
            cur.Next = head2
            cur = head2
            head2 = head2.Next
        }
    }

    if head1 != nil {
        cur.Next = head1
    }
    if head2 != nil {
        cur.Next = head2
    }

    return headNew.Next
}

总结

源码参考
算法源码
单元测试

作者头像

刘宇帅

非著名程序员,全栈开发工程师,长期专注系统开发与架构设计。

提示

功能待开通!


暂无评论~

相关文章

Go 语言实现算法之冒泡排序

冒泡排序是最基本的排序算法,它的复杂度为O(n²)。 它的实现原理非常简单,就是从头遍历数组,如果第 i 个数比第 i + 1 个数大,那么就交换他们,这样遍历第一次就会让最大的数放到数组末尾,第二遍会把第二大的数放到数组倒数第二的位置,依次类推…… 冒泡排序过程图形表示如下: 那么我们可以实现最基本的冒泡排序如下: func BubbleSort1(list []int) { n := len(list) for i := 0; i &lt; n; i++ { for j := 0; j &lt; n-1; j++ { if list

【每日一题】我为什么喜欢面试链表反向打印

题目 输入一个单链表链表的头结点,从尾到头打印每个节点的值。 题目很简单但是实现方法却可以有很多种,也能考察人的不同方面的知识。这里实现使用 go 语言。 实现 节点定义 首先说明这里不能使用各语言内置的链表,比如 java 的 LinkedList。这里要求的单链表只能有两个属性不能有其他的属性和方法。 go 语言定义如下 type ListNode struct { Val int Next *ListNode } 堆栈 or 数组 看到这个题目最先想到的就是用堆栈或数组来做,方法就是遍历所有节点放入到数组或堆栈然后再遍历打印。数组就比较简单了,这里写下堆栈的实现。 首先

嵌套循环性能

下面有两个函数,猜一下哪一个执行的快 func nestFor1() { a := 0 for i := 0; i &lt; 10000000; i++ { for j := 0; j &lt; 2; j++ { a = a + i a = a + j } } } func nestFor2() { a := 0 for i := 0; i &lt; 2; i++ { for j := 0; j &lt; 10000000; j++ {