合并两个排序的链表的多种解决方法(java)

合并两个排序的链表的三种方法

        b4e5509b63274e0db182072f3c1aada7.png

1,使用数组解决

        利用ArrayList<Integer>建立数组,存储链表中的数据,存储之后利用函数Collections.sort()将链表进行排序,排序之后数据是我们需要的顺序,之后建立新的链表把数据存储进来。

        原理如图:

37227415914549aa9b2c5eb96f0e0c33.png

        代码如下:

public ListNode Merge(ListNode pHead1,ListNode pHead2) {
	//先检查list1 list2为空的情况
	if(pHead1==null) return pHead2;
	if(pHead2==null) return pHead1;
	if(pHead1 == null && pHead2 == null){
		return null;
	}
	//将两个两个链表存放在list中
	ArrayList<Integer> list = new ArrayList<>();
	//遍历链表pHead1,存储pHead1中的数据
	while(pHead1!=null){
		list.add(pHead1.val);
		pHead1 = pHead1.next;
	}
	//遍历链表pHead2,存储pHead2中的数据
	while(pHead2!=null){
		list.add(pHead2.val);
		pHead2 = pHead2.next;
	}
	//利用函数对数组list进行排序
	Collections.sort(list);
	//最后将list转换为新的链表newHead
	ListNode newHead = new ListNode(list.get(0));
	ListNode cur = newHead;
	for(int i=1;i<list.size();i++){
		cur.next = new ListNode(list.get(i));
		cur = cur.next;
	}
	return newHead;
}

2,遍历

       这个方法的本质就是遍历两个链表把小的数据拿出来,放入新的链表的节点

        先设置newHead为新节点,放置于新链表之前,最后返回的就是newHead.next;按照顺序遍历两个链表,把小的数据存入新的链表中,然后更新链表。其中当任何一个节点为null的时候退出循环,记得最后把还没比较的数据都存入新链表中。

原理如下:

9569686e7ab24117b2033e56d45e5967.png

代码如下:

public ListNode Merge(ListNode pHead1, ListNode pHead2) {
	// 先判断两个链表是否为空链表
	if (pHead1 == null || pHead2 == null) {
		return pHead1 != null ? pHead1 : pHead2;
	}
	// 建立新的链表来存储数据
	ListNode newHead = new ListNode(-1);
    // 保存newHead的地址,留着进行最后数据的返回
	ListNode returnHead = newHead;
	// 当其中任何一个节点为null时候退出循环比较
	while (pHead1 != null && pHead2 != null) {
		if (pHead1.val < pHead2.val) {
			newHead.next = pHead1;
			pHead1 = pHead1.next;
		} else {
			newHead.next = pHead2;
			pHead2 = pHead2.next;
		}
		//每次比较完成之后更新新节点
		newHead = newHead.next;
	}
	// 别忘了循环结束之后还需要拼接未对比的链表
	newHead.next = pHead1 == null ? pHead2 : pHead1;
	return returnHead.next;
}

3,递归

        最后的,也是最难理解的方法就是递归,但是使用递归方法的逻辑很简洁。利用递归的特色,找到最终的节点。

        利用递归找到最大的一个节点,在返回的过程中不断更新节点,使得前一个节点小于后一个节点。最后把整理好的节点进行返回。

        原理图就不画了(抱歉,有点难画):

        代码如下;

public ListNode Merge(ListNode pHead1, ListNode pHead2) {
	//当其中一个链表已经为null的时候
	//说明另一个链表中的数据一定为大的数据
	//所以,返回另一个链表的数据
	if (pHead1 == null || pHead2 == null) {
		return pHead1 != null ? pHead1 : pHead2;
	}
	// 两个链表元素依次对比
	if (pHead1.val < pHead2.val) {
		// 递归计算 
		// 把小的数据作为前节点,用于接受大的返回值
		pHead1.next = Merge(pHead1.next, pHead2);
		// 返回当前节点,用于和前节点的拼接和最终的返回
		return pHead1;
	} else {
		// 递归计算
		pHead2.next = Merge(pHead1, pHead2.next);
		return pHead2;
	}
}

 

总的来说这个题目的难点比较低。

核心部分就是想办法建立新的链表,把原先两个链表的数据按照顺序接入新的链表当中。

加油尽可能的去使用递归来解决这道题目!!

                                                        加油同学!!!

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值