【剑指offer】25、合并两个排序的链表

题目:

        输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。

分析:

特殊情况:

        当list1为空,则直接返回list2即可。

        当list2为空,则直接返回list1即可。

        当list1和list2都为空,则直接返回空。

一般情况:

        比较list1和list2的值,值小的节点也是合并后链表的最小节点,这个节点就是合并链表的头节点,记为head;在之后的步骤里,哪个链表的头节点的值更小,另一个链表的所有节点都会一次插入到这个链表中。

        设head所在的链表是链表1,另一个链表是链表2。准备一个指针cur1,指向第一个链表的头部;准备一个指针cur2,指向第二个链表的头部。链表1和链表2都从头部开始遍历,比较每次遍历的两个节点的值。

        设定ListNode类型的变量pre,用来记录每次比较结果中较小的值,一开始pre指向的是null。

        设定ListNode类型的变量next,用来存放cur2指向的后面的一个值。       

        当链表1头部的值大于链表2头部的值的时候,

                pre指向cur1

                cur1指向cur1的下一个位置 

        当链表1头部的值大于链表2头部的值的时候,

                next保存cur2的后一个位置

                pre的next指向cur2

                cur2的next指向cur1

                因为现在是cur2指向的数较小,于是将pre改为当前的cur2指向的位置

                然后继续遍历这个链表的下一个节点,于是将cur2指向next

          如果链表1先遍历完,则cur指向null,pre是链表1最后一个节点,就把pre的next指针指向链表二的当前节点(cur2),即将链表2没有遍历的有序部分全部添加到list1后面。

          如果链表2先走完,则代表list2中所有的点都已经插入到了list1当中,遍历结束。 

          最后,返回合并后的链表头head。

package swordOffer;

import java.awt.List;
import java.util.LinkedList;

import org.w3c.dom.Node;

/*
 * 
 * 输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
 * 
 * 
 * */
public class ListNodeMerge {
//非递归版
	public static ListNode merge(ListNode list1, ListNode list2) {
		if(list1 == null ) {
			return list2;
		}
		if(list2 == null) {
			return list1;
		}
		if(list1 == null && list2 == null) {
			return null;
		}
		
		//合并后单链表头结点
		ListNode head = list1.val < list2.val? list1 : list2;
		ListNode cur1 = head == list1 ? list1 : list2;
		ListNode cur2 = head == list1 ? list2 : list1;
		
		ListNode pre = null;
		ListNode next = null;
		
		while(cur1 != null && cur2 != null) {
			if(cur1.val <= cur2.val) {
				pre = cur1;
				cur1 = cur1.next;
			}else {
				next = cur2.next;
				pre.next = cur2;
				cur2.next = cur1;
				pre = cur2;
				cur2 = next;
			}
		}
		
		return head;
	}
	
//递归版
//	public static ListNode merge(ListNode list1, ListNode list2) {
//		if(list1 == null && list2 == null) {
//			return null;
//		}
//		if(list1 == null) {
//			return list2;
//		}
//		if(list2 == null) {
//			return list1;
//		}
//		ListNode mergeNode = null;
//		if (list1.val < list2.val) {
//			mergeNode = list1;
//			mergeNode.next = merge(list1.next, list2);
//		} else {
//			mergeNode = list2;
//			mergeNode.next = merge(list1, list2.next);
//		}
//		
//		return mergeNode;
//	}


	public static void main(String[] args) {
		ListNode node1 = new ListNode(1);
		node1.next = new ListNode(5);
		node1.next.next = new ListNode(6);

		ListNode node2 = new ListNode(2);
		node2.next = new ListNode(3);
		node2.next.next = new ListNode(5);
		
		ListNode head = merge(node1, node2);
		while(head != null) {
			System.out.print(head.val + " ");
			head = head.next;
		}
	}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值