两个有序链表的合并 java

两个有序链表序列的合并

分数 20

已知两个非降序链表序列S1与S2,设计函数构造出S1与S2合并后的新的非降序链表S3。

输入格式:

输入分两行,分别在每行给出由若干个正整数构成的非降序序列,用−1表示序列的结尾(−1不属于这个序列)。数字用空格间隔。

输出格式:

在一行中输出合并后新的非降序链表,数字间用空格分开,结尾不能有多余空格;若新链表为空,输出NULL

输入样例:
1 3 5 -1
2 4 6 8 10 -1
输出样例:
1 2 3 4 5 6 8 10

这个题一眼看上去不难,就是双指针的应用,两个指针分别指向两个数组,然后比较大小后放进新的数组,代码如下:

import java.util.Scanner;
public class L1010_ {
    public static void main(String[] args) {
        Scanner sc =new Scanner(System.in);//创建Scanner类
        String[] str1=sc.nextLine().split(" ");//String类的split分割方法,可以根据传入的字符串参数将字符串分割成数组
        String[] str2=sc.nextLine().split(" ");//将两个链表分割成两个字符串数组
        int[] arr1=new int[str1.length];//创建整数数组,用于储存数字方便后续处理
        int[] arr2=new int[str2.length];
        for(int i=0;i<arr1.length;i++){
            arr1[i]= Integer.parseInt(str1[i]);//调用Integer类的parseInt方法将String转换成int
        }
        for(int i=0;i<arr2.length;i++){
            arr2[i]=Integer.parseInt(str2[i]);//将两个字符串数组转换成整数数组,方便比较
        }
        int[]arr=new int[arr1.length+ arr2.length-2];//创建合并后的数组,因为原始数组都是以-1结尾,所以要将结尾的-1忽略掉,所以-2
        int id=0;//合并后的数组指针
        int left1=0;//arr1的指针
        int left2=0;//arr2的指针
        //因为这两个链表是非降序的,所以就是升序排序的数组,所以从左往右依次比较,
        //数字小的就放入合并后的数组,然后将指针后移,进行下次比较
        //直到有一个数组所有数字都放进了,合并数组里,此时结束循环
        //然后判断哪个数组没有放进去,再将未放进去的数字都依次放进去
        while(left1<arr1.length-1&&left2<arr2.length-1){
            if(arr1[left1]<arr2[left2]){//每次通过从arr1 arr2的下标访问元素,然后比较
                arr[id++]=arr1[left1++];//小的就放进合并数组arr里,并将下标++,也就是后移
            }else{
                arr[id++]=arr2[left2++];
            }
        }
        if(left1==arr1.length-1){//判断哪个数组没有全部访问玩,
            for(int i=left2;i<arr2.length-1;i++){
                arr[id++]=arr2[i];//将剩下的数字依次放入合并数组中
            }
        }else{
            for(int i=left1;i<arr1.length-1;i++){
                arr[id++]=arr1[i];
            }
        }
        if(arr.length==0){//再根据合并数组大小判断答案,若数组大小为0则两个数组都为空,此时输出NULL
            System.out.print("NULL");
        }else{
            System.out.print(arr[0]+"");//不为空时就依次输出合并数组的元素
            for(int i=1;i<arr.length-1;i++){
                System.out.print(" "+arr[i]);
            }
        }
    }
}

但是java提交上去,最后一个测试点一直超时(或者内存超限),这个题的难点就在这里,因为java的输入(Scanner)输出(System.out.println())相比c语言来说,要慢的多。
在这里插入图片描述

在数据量小得情况下还好,一旦数据量大起来就特别容易超时,此题用Scanner输入就会超时,所以就需要更快得输入 BufferedReader:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
	public static void main(String[] args) throws java.io.IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); // 创建BufferedReader类
		String line = br.readLine(); // 输入的一行字符
		System.out.println(line);
	}
}

用BufferedReader类进行读取时,会有一个异常:IOException,用try代码太多,就在主类后面throw抛出就好了:throws java.io.IOException

这时我们将输入的Scanner类改成BufferedReader类

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Scanner;
public class Main {
    public static void main(String[] args) throws java.io.IOException{
        BufferedReader br =new BufferedReader(new InputStreamReader(System.in));
        String[] str1=br.readLine().split(" ");//读入一行数组再进行处理
        String[] str2=br.readLine().split(" ");
    }
}

在这里插入图片描述

此时提交还是会显示超时,所以还需要优化代码,现在还有一个优化的一个点就是输出,java的输出也是很慢的,所以就有了快速输出:BufferedWriter类

创建格式跟BufferedReader类 类似

BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(System.out));
bw.write("NULL");//输入缓冲区
bw.flush();//输出控制台,write后面必须跟这个,否则就会打印不出来

将输出用的System.out.print(),全部换成BufferedWriter,

此时代码就为:

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

public class Main {
    public static void main(String[] args) throws java.io.IOException{
        BufferedReader br =new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(System.out));
        String[] str1=br.readLine().split(" ");
        String[] str2=br.readLine().split(" ");
        int[] arr1=new int[str1.length];
        int[] arr2=new int[str2.length];
        for(int i=0;i<arr1.length;i++){
            arr1[i]= Integer.parseInt(str1[i]);
        }
        for(int i=0;i<arr2.length;i++){
            arr2[i]=Integer.parseInt(str2[i]);
        }
        int[]arr=new int[arr1.length+ arr2.length-2];
        int id=0;
        int left1=0;
        int left2=0;
        while(left1<arr1.length-1&&left2<arr2.length-1){
            if(arr1[left1]<arr2[left2]){
                arr[id++]=arr1[left1++];
            }else{
                arr[id++]=arr2[left2++];
            }
        }
        if(left1==arr1.length-1){
            for(int i=left2;i<arr2.length-1;i++){
                arr[id++]=arr2[i];
            }
        }else{
            for(int i=left1;i<arr1.length-1;i++){
                arr[id++]=arr1[i];
            }
        }
        if(arr.length==0){
            bw.write("NULL");
            bw.flush();
        }else{
            bw.write(arr[0]+"");//这里要注意,直接输出数字可能输出乱码,要加上一个空字符,将它变成字符串类型再输出就不会变成乱码了
            for(int i=1;i<arr.length;i++){
                bw.write(" "+arr[i]);
            }
            bw.flush();
        }
    }
}

String类split() 方法:
https://www.runoob.com/java/java-string-split.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值