1.题目:
链接:https://www.nowcoder.com/questionTerminal/a479a3f0c4554867b35356e0d57cf03d
来源:牛客网
Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists.
2.想法:合并两个已经排好序的链表;返回新的链表必须由两个链表的头部拼接而成
3.主要思路:1.判断空值情况;2.判断两个链表的大小,如果是更小的,则插入临时结点tmp;3.递归循环
4.代码:
public class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
if(l1==null) return l2;
if(l2==null) return l1;
if(l1.val<l2.val){
ListNode tmp = l1;
tmp.next = mergeTwoLists(l1.next,l2);
return tmp;
}else{
ListNode tmp = l2;
tmp.next = mergeTwoLists(l1,l2.next);
return tmp;
}
}
}
5.总结是否有更好的办法:
这个是我刷LeetCode的第一个题目,由于对java的链表使用不熟悉,所以从easy入手,这个题目的思路是看到别的网友之后写出来的;因为使用到了递归,时间效率比较低,虽然通过了所有用例,肯定还有效率更高的办法,稍微总结几点:
1)使用效率更高的数据结构;
2)使用效率更高的排序算法;
3)同时使用效率更高的数据结构和使用效率更高的排序算法
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
/*
思路:
1.输入问题:考虑为空!
2.新链表的第一个结点问题,由于一般情况下第一个结点都需要特殊处理,比较实用的解决办法是在第一个结点前增加一个虚拟的头结点(例如下面的head),讲实际的第一个结点一般化。最后输出的时候输出这个虚拟结点的下一个结点就OK
3.如何为新链表选择下一个结点(已经虚拟出第一个结点了。)这个比较容易,比大小就OK了。取小的并并在此链表前进一步。
4.注意循环的终止条件!
5.终止后并没有结束!
*/
public class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode head= new ListNode(0);//问题2 定义头结点
ListNode p = head;
while(l1!=null&&l2!=null){//问题3和4
if(l1.val<=l2.val){
p.next=l1;
l1=l1.next;
}else{
p.next=l2;
l2= l2.next;
}
p=p.next;
}
if(l1!=null){//问题1和5
p.next=l1;
}
if(l2!=null){
p.next=l2;
}
return head.next;//返回头结点后面的链表
}
}
6.注:算法题需要多看多做多总结,对数据结构熟悉使用,对排序算法等的熟悉使用。
所有代码一定要自己手动敲一遍,因为自己敲大概率不能一次过,调错误的过程就是一次学习的过程
7.大家思考问题的方式不一样主要是因为大家肚子里装的货不一样。所以多总结。
--------------------------------------------------------------------------
题目描述
给定两个升序的单链表的头节点 head1 和 head2,请合并两个升序链表, 合并后的链表依然升序,并返回合并后链表的头节点。
输入描述:
两个升序的单链表的头节点 head1 和 head2
输出描述:
在给定的函数内返回新链表的头指针。
示例1
输入
复制
5 1 2 3 4 5 6 7 8 9 10 11 12
输出
复制
1 2 3 4 5 7 8 9 10 11 12
-----------------
生长学习法---思路报告:
重要问题:
1.合并两个已经排好序的链表;要求合并后也有序;
直觉解法:
1.输入---使用BufferReader
2.申请一个新的空间链表,然后新建一个结点tmp;
3.比较两个链表所指向的结点的val;
4.小的插进新链表;
5.返回即可;
解决方法的可能性:
新建一个空间链表;
递归解决;
解决方案:
主要涉及的是数据结构的基础;
数据结构:
链表;
算法复杂度:时间空间
时间复杂度O(n)
空间复杂度O(1)
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
public class Main {
private static StreamTokenizer in =
new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
public static ListNode merge(ListNode list1, ListNode list2) {
ListNode head = new ListNode(0);
ListNode current = head;
ListNode p1 = list1;
ListNode p2 = list2;
while (p1 != null && p2 != null) {
if (p1.val < p2.val) {
current.next = p1;
current = p1;
p1 = p1.next;
} else {
current.next = p2;
current = p2;
p2 = p2.next;
}
}
current.next = p1 == null ? p2 : p1;
return head.next;
}
private static ListNode read() {
int size = nextInt();
ListNode head = new ListNode(0);
ListNode last = head;
for (int i = 0; i < size; i++) {
ListNode next = new ListNode(nextInt());
last.next = next;
last = next;
}
return head.next;
}
public static class ListNode {
int val;
ListNode next;
public ListNode(int val) {
this.val = val;
}
}
private static int nextInt() {
try {
in.nextToken();
return (int) in.nval;
} catch (Exception exception) {
throw new RuntimeException(exception);
}
}
public static void main(String[] args) {
ListNode head1 = read();
ListNode head2 = read();
ListNode head = merge(head1, head2);
StringBuilder sb = new StringBuilder();
while (head != null) {
sb.append(head.val).append(" ");
head = head.next;
}
System.out.println(sb.toString());
}
}