合并两个有序的单链表

题目:
给定两个有序单链表头节点 head1 和 head2 请合并两个有序链表,合并后依然有序,并返回合并后的头节点。
例如:
0->2->3->7->null
1->3->5->7->9->null
合并后的链表为:0->1->2->3->3->5->7->7->9->null
解答:
假设两个链表长度分别为 M 和 N 直接给出时间复杂度为 O(M+N), 额外空间复杂度为 O(1) 的方法,具体过程如下:
1、 如果两个链表有其中一个为空,说明无需合并过程,返回另一个链表的头节点即可。
2、 比较 head1 和 head2 的值,小的节点也是合并后链表的最小节点,这个节点应该是合并后链表的头节点,记作 head,之后的步骤中哪个链表的头节点值更小要把另一个链表的所有节点都会依次插入到个链表中来。
3、 不妨设 head 头节点所在的链表为 链表1 ,另一个链表为 链表2 ,链表1 和 链表2 都从头部开始一起遍历,比较每次遍历到两个节点的值,记作 cur1 和 cur2 然后根据大小不同的关系做出调整,同时用一个变量 pre 表示上次比较时值较小的节点。
例如:链表1 为1->5->6->null,链表2 为 2->3->7->null。
cur1 = 1, cur2 = 2, pre = null。cur1 小于 cur2 不做调整因为此时 cur1 较小,所以令 pre = cur  = 1,然后继续遍历链表1 的下一个节点,也就是节点 5。
cur1 = 5, cur2 = 2, pre = 1, cur2 小于 cur1 让 pre 的 next 指针指向 cur2, cur2 的 next 指针指向 cur1, 这样,cur2便插入到链表1之中了。因为此时的cur2 较小所以令pre = cur2 = 2,然后继续遍历链表2 的下一个节点也就是节点3 ,这一步完成后,链表1变为1->2->5->6->null , 链表2 变为 3->7->null, cur1 = 5, cur2 = 3, pre = 2。
cur1 = 5, cur2 = 3, pre = 2, 此时又是 cur2 较小,与上一步调整类似,这一步完成后,链表1变为 1->2->3->5->6->null,链表2变为7->null,cur1 = 5,cur2 = 7,pre = 3。
cur1 = 5, cur2 = 7, pre = 3, cur1 小于 cur2 不用做调整,因为此时 cur1 较小,所以令 pre = cur1 = 5, 然后继续遍历链表1 的下一个节点,也就是节点6。
cur1 = 6, cur2 = 7, pre = 5, cur1 小于 cur2 不用做调整,因为此时 cur1 较小,所以令 pre = cur1 = 6, 此时已经走到了链表1 的末尾,再往下就结束了,链表1或者链表2 有任何一个结束的话,就进入到步骤4。
4、 如果链表1 先走完,此时 cur1 = null, pre 为 链表1 的最后一个节点,那么就把 pre 的 next 指针指向 链表2 的当前节点(cur2),表示把链表2没有遍历完的的部分拼接到最后,如果 链表2 先结束说明 链表2 中的元素全部插入到里面。
public class Node{
             public int value ;
             public Node next ;
            
             public Node( int data){
                   this . value = data;
            }
      }
       public Node merge(Node head1, Node head2){
             if (head1 == null || head2 == null ){
                   return head1 != null ? head1 : head2;
            }
            Node head = head1. value < head2. value ? head1 : head2;
            Node cur1 = head == head1 ? head1 : head2;
            Node cur2 = head == head1 ? head2 : head1;
            Node pre = null ;
            Node next = null ;
             while (cur1 != null && cur2 != null ){
                   if (cur1. value <= cur2. value ){
                        pre = cur1;
                        cur1 = cur1. next ;
                  } else {
                        next = cur2. next ;
                        pre. next = cur2;
                        cur2. next = cur1;
                        pre =cur2;
                        cur2 = next;
                  }
            }
            pre. next = cur1 == null ? cur2 : cur1;
             return head;
      }

参考资料:《程序员面试代码指南》左程云 著


猜你喜欢

转载自blog.csdn.net/young_1004/article/details/80687609
今日推荐