[LeetCode][链表easy]merge-two-sorted-lists(java)

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());
    }
}

 

 

 

 

 

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值