合并两个排序的链表

153 阅读1分钟

输入两个递增的链表,单个链表的长度为n,合并这两个链表并使新链表中的节点仍然是递增排序的。

数据范围:0<=n<=1000 , -1000<=节点值<=1000 要求:空间复杂度 O(1),时间复杂度 O(n)

  • 首先简单实现一个链表

    class Node{
        constructor(ele){
            this.element=ele
            this.next=undefined
        }
    }
    ​
    class LinkList{
        constructor(){
            this.head=undefined
            this.count=0
        }
        push(ele){
            const node =new Node(ele)
            if(!this.head){
                this.head=node
            }else{
                let current = this.head
                while(current.next){
                    current=current.next
                }
                current.next=node
            }
            this.count++
        }
        remove(idx){
            if(idx>=0&&idx<this.count){
                let current=this.head
                if(idx==0){
                    this.head=current.next
                }else{
                    let pre;
                    for(let i=0;i<idx;i++){
                        pre=current
                        current=current.next
                    }
                    pre.next=current.next
                    this.count--
                    return current
    ​
                }
            }else{
                return undefined
            }
        }
        getElementByIdx(idx){
            if(idx>=0&&idx<this.count){
                let current=this.head
                for(let i=0;i<idx;i++){
                    current=current.next
                }
                return current
            }else{
                return undefined
            }
        }
    }
    ​
    
  • 如何实现两个有序链表合并且排序 ?

    • 方法一 (迭代求解)

    技巧: 创建单链表,设一个虚拟头结点,也叫哨兵,因为这样每一个结点都有一个前驱结点。

    1. 初始化一个cur

    2. 判断pHead1的值是否大于pHead2的值 ,如果pHead1值小,则将cur的next指针指向pHead1, 然后pHead1指向下一个节点

    3. 循环步骤2 , 直到pHead1和pHead2为空

    4. 将pHead1剩下的部分或pHead2剩下的部分,加入到cur的后面

      function Merge(phead1,phead2){
          let head=new Node(-1)
          let cur=head
          while(phead1&&phead2){
              if(phead1.element<=phead2.element){
                      cur.next=phead1
                      phead1=phead1.next
               }else{
                      cur.next=phead2
                      phead2=phead2.next
               }      
              cur=cur.next    //cur 指向下一个节点
          }
          cur.next=phead1 ? phead1 :phead2
          return head.next
      }
      
    • 方法二(递归实现)

    目的 : 合并两个单链表,返回两个单链表头结点值小的那个节点。

    function Merge(phead1,phead2){
        if(!phead1) return phead2
        if(!phead2) return phead1
        if(phead1.element<=phead2.element){
            phead1.next=Merge(phead1.next,phead2)
            return phead1
        }else{
            phead2.next=Merge(phead1,phea2.next)
            return phead2
        }
    }