每日一题 为了工作 2020 0406 第三十五题

/**
 *
 * 问题:合并两个有序的单链表
 *     给定两个有序单链表的头节点 head1和head2, 请合并两个有序链表, 合并后的链表依然有序,
 *     并返回合并后链表的头节点。
 * 	       例如:
 *	   0->2->3->7->null
 *     1->3->5->7->9->null
 *     合并后的链表为: 0-> 1->2->3->3->5->7->7->9->null
 *
 * 解答:
 * 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=cur1=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的所有节点都已经插入到链表l中,调整结束。
 *
 * 5. 返回合并后链表的头节点head。
 *
 * @author 雪瞳
 *
 */

  

public class Node {

	public int value;
	public Node next;
	public Node(int data){
		this.value=data;
	}
}

  

public class MergeNode {

	public Node mergeNode(Node head1,Node head2){

		if(head1 == null || head2 == null){
			return head1 == null?head2:head1;
		}
		Node head = head1.value<head2.value?head1:head2;

		// current 1 存储的是较小的元素
		// current 2 存储的是较大的元素
		Node current1 = head == head1 ? head1:head2;
		Node current2 = head == head1 ? head2:head1;
		// 存放当前current1和current2中最小的元素
		Node preCurrent = null;
		Node nextCurrent = null;

		while(current1 != null && current2 != null){

			if(current1.value <= current2.value){
				// 1 < 2 继续遍历直到出现 2 < 1 的情况
				preCurrent = current1;
				current1 = current1.next;
			}else{
				// 1 > 2 将节点2的当前元素插入到 1 中
				nextCurrent = current2.next;
				preCurrent.next = current2;
				current2.next = current1;

				preCurrent = current2;
				current2 = nextCurrent;
			}

		}
		preCurrent.next = current1==null?current2:current1;

		return head;
	}
}

  

public class TestMergeNode {

	public static void main(String[] args) {

		TestMergeNode test = new TestMergeNode();
		MergeNode merge = new MergeNode();

		Node n1 = new Node(1);
		Node n2 = new Node(2);
		Node n3 = new Node(3);
		Node n4 = new Node(4);
		Node n5 = new Node(5);
		Node n6 = new Node(6);
		Node n7 = new Node(7);
		Node n8 = new Node(8);
		Node n9 = new Node(9);

		n1.next = n2;
		n2.next = n3;
		n3.next = n4;
		n4.next = n5;
		Node head1 = n1;

		n6.next=n7;
		n7.next=n8;
		n8.next=n9;
		Node head2 = n6;

		test.showNodeList(head1);
		test.showNodeList(head2);
		Node result = merge.mergeNode(head1, head2);
		test.showNodeList(result);
	}
	/*获取链表
	public Node getNodeList(int length){
		Random rand = new Random();
		Node nodeArray[]= new Node[length];
		for(int i=0;i<length;i++){
			nodeArray[i]=new Node(rand.nextInt(10));
		}
		for(int i=0;i<length-1;i++){
			nodeArray[i].next = nodeArray[i+1];
		}
		return nodeArray[0];
	}*/
	//显示列表元素
	public void showNodeList(Node head){
		Node current = null;
		current = head;
		System.out.println("链表元素如下...");
		while(current!=null){
			System.out.print(current.value+"\t");
			current=current.next;
		}
		System.out.println();
	}
}

  

原文地址:https://www.cnblogs.com/walxt/p/12641597.html

时间: 2024-11-06 17:23:08

每日一题 为了工作 2020 0406 第三十五题的相关文章

每日一题 为了工作 2020 0405 第三十四题

/** * 问题: 向有序的环形单链表中插入新节点 * 一个环形单链表从头节点 head开始不降序, 同时由最后的节点指回头节点.给定这样 * 一个环形单链表的头节点 head和一个整数 num, 请生成节点值为 num的新节点,并插入到 * 这个环形链表中, 保证调整后的链表依然有序. * * 解题: * 1. 生成节点值为 num的新节点, 记为 node. * 2. 如果链表为空, 让 node自己组成环形链表, 然后直接返回node. * 3. 如果链表不为空, 令变量 pre=head

每日一题 为了工作 2020 0305 第三题

/** * 问题: * 如何仅适用递归函数和栈操作逆序一个栈 * 一个栈依次压入1.2.3.4.5,那么从栈顶到栈底分别为5.4.3.2.1.将这个栈转置后, * 从栈顶到栈底为5.4.3.2.1,也就是实现了栈中元素的逆序,但是只可以通过递归函数来实现. * 分析: * 本题目考验查找操作和递归函数的设计,我们需要设计出两个递归函数. * 函数一:将栈stack中的栈底元素返回并移除 * getAndRemoveLastElement() * 函数二:逆序一个栈 * @author 雪瞳 *

每日一题 为了工作 2020 04011 第四十题

/** * * 问题: * 判断字符数组中是否所有的字符都只出现一次 * 给定一个字符类型的数组chars[],判断 chars中是否所有的字符都只出现过一次. * * 要求: * 时间复杂度为 O(N) * 解答: * 遍历一遍 chars, 用 map记录每种字符的出现情况, 这样就可以在遍历时发现字符重复 * 出现的情况, map可以用长度固定的数组实现, 也可以用哈希表实现. * * @author 雪瞳 * */ public class IsUniquel { public stat

LeetCode第三十五题-寻找数组中对应目标值的首尾索引

Search Insert Position 问题简介:寻找数组中元素与target的关系 注: 1.target小于数组所有元素时返回0 2.target大于数组所有元素时返回数组长度 3.target不包含于数组元素中,但取值区间在其中,返回对应的索引 举例: 1: 输入: [1,3,5,6], 5 输出: 2 2: 输入: [1,3,5,6], 2 输出: 1 3: 输入: [1,3,5,6], 7 输出: 4 4: 输入: [1,3,5,6], 0 输出: 0 解法一:比较简单的解法就是

剑指Offer(Java版)第三十五题:给一个数组,返回它的最大连续子序列的和

/*HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学.今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决.但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止).给一个数组,返回它的最大连续子序列的和,你会不会被他忽悠住?(子向量的长度至少是1) */ import java.util.*; publ

经典算法题每日演练——第二十五题 块状链表

原文:经典算法题每日演练--第二十五题 块状链表 在数据结构的世界里,我们会认识各种各样的数据结构,每一种数据结构都能解决相应领域的问题,每一种数据结构都像 是降龙十八掌中的某一掌,掌掌毙命... 当然每个数据结构,有他的优点,必然就有它的缺点,那么如何创造一种数据结构 来将某两种数据结构进行扬长避短,那就非常完美了.这样的数据结构也有很多,比如:双端队列,还有就是今天讲的 块状链表, 我们都知道 数组 具有 O(1)的查询时间,O(N)的删除,O(N)的插入... 链表 具有 O(N)的查询时

经典算法题每日演练——第十五题 并查集

原文:经典算法题每日演练--第十五题 并查集 这一篇我们看看经典又神奇的并查集,顾名思义就是并起来查,可用于处理一些不相交集合的秒杀. 一:场景 有时候我们会遇到这样的场景,比如:M={1,4,6,8},N={2,4,5,7},我的需求就是判断{1,2}是否属于同一个集合,当然实现方法 有很多,一般情况下,普通青年会做出O(MN)的复杂度,那么有没有更轻量级的复杂度呢?嘿嘿,并查集就是用来解决这个问题的. 二:操作 从名字可以出来,并查集其实只有两种操作,并(Union)和查(Find),并查集

code第一部分数组:第十五题 矩阵翻转(图像翻转)

code第一部分数组:第十五题 矩阵翻转(图像翻转) 首先想到,纯模拟,从外到内一圈一圈的转,但这个方法太慢.如下图,首先沿着副对角线翻转一次,然后沿着水平中线翻转一次. 源代码 #include <iostream> #include <vector> using namespace std; //引用类型形参 void swap(int &n,int &m) { int temp=n; n=m; m=temp; } //指针类型形参 void swap1(int

工作那些事(三十二)由孙悟空的两个故事谈个人与团队

故事一: 话说唐太宗为了节省开支,西天取经项目需要裁员,接到通知的唐僧骤然头大,不知如何是好. 有人说: 先把猴子开了,因为不服从管理,再把沙僧开了,因为没有主见,再把猪开了, 因为猪肉比较贵,直接杀了卖钱,再把自已开了,因为没本事去,小白龙留下,因为有后台. 但是: 猴子是不能开的,猴子是团队中的精英,也就是大牛. 小白龙是不能开的,他是唐僧的座驾,是他身份的象征. 猪也是不能开的,对团队的氛围有重要作用. 最后 只能开掉沙僧 虽然他做事很多. 重要的是四种人: 1 唐僧:钦定的项目经理,虽然