网易校招编程题--操作序列(Java实现)

题目描述

小易有一个长度为n的整数序列,a_1,...,a_n。然后考虑在一个空序列b上进行n次以下操作:
1、将a_i放入b序列的末尾
2、逆置b序列
小易需要你计算输出操作n次之后的b序列。

我相信大家看到这个题目时第一反应就是每次取一个数出来加到数组末尾然后倒序,循环。。。。这样的结果对于10的9次方个数,肯定是超时的。

熟悉指针的同学可能就想到了,新建一个空链表,奇数往右边加,偶数往左边加,在输出时如果数组长度是偶数则正向输出反之倒序输出,这个想法和我最初的想法一样,涉及到插入操作时概率快的当然选LinkedList了

(1)往右加入1,序列是1,反向打印为1满足操作要求

(2)往左加入2,序列是21,正向打印21满足操作要求

(3)往右加入3,序列是213,反向打印312满足操作要求

(4)往左加入4,序列是4213,正向打印4213满足操作要求

什么规律我就不多BB了。来吧直接上代码:

        Scanner input = new Scanner(System.in);
        String num = input.nextLine();
        String line = input.nextLine();
        String []s = line.split(" ");
        List<String> list = new LinkedList<>();
        for (int i=0;i<s.length;i++){
            if(i%2 == 0){
                ((LinkedList<String>) list).addLast(s[i]);
            }
            else{
                ((LinkedList<String>) list).addFirst(s[i]);
            }
        }
        if(Integer.parseInt(num)%2 == 0){
            for (int i=0;i<list.size();i++) {
                if(i != list.size()-1)
                    System.out.print(list.get(i) + " ");
                else
                    System.out.print(list.get(i));
            }
        }else {
            for (int i=list.size() - 1; i >= 0; i--) {
                if(i != 0)
                    System.out.print(list.get(i) + " ");
                else
                    System.out.print(list.get(i));
            }
        }

能想到这个的,说明成功了一半了,因为知道这个序列的规律了,只是由于要操作大量元素,虽然LinkedList比ArrayList快了很多,但是在提交时还是超时,case通过50%。

由于数太大了,因而能不能只遍历一次,并且不能数组进行操作。那么换个思路:

(1)s[] = {1}直接打印,输出1

(2)s[] = {1,2},输出21,数组长度length=2,2%2==0,序列前半部分为s[length-1]=2,后半部分为s[0]=1,所以输出21.

(3)s[] = {1,2,3},输出312,数组长度length=3,3%2==1,序列前半部分为s[length-1]=3,s[length-1-2]=1,后半部分为s[1]=2,所以输出312.

(4)s[] = {1,2,3,4},输出4213,数组长度length=4,4%2==0,序列前半部分为s[length-1]=4,s[length-1-2]=2,后半部分为s[0]=1,s[0+2]=3,所以输出4213.

不知道你们看明白了没有,如果length%2==0那么后半部分从0开始,反之从1开始,不管怎样,前半部分总是从最后一个开始,那么现在就可以写了:

(1)分两半,前半部分从后向前,后半部分从前向后,那么就要有两个索引标志,且定义preIndex和lastIndex

(2)当length%2==0时,preIndex初始为0;当length%2==0时,preIndex初始为1,lastIndex都是初始为length-1

(3)当length%2==0时,lastIndex %2 == 1才输出,输出后lastIndex 自减2,preIndex %2 == 0才输出,输出后preIndex 自增2

(4)当length%2==1时,lastIndex %2 == 0才输出,输出后lastIndex 自减2,preIndex %2 == 1才输出,输出后preIndex 自增2

最终代码:

        Scanner input = new Scanner(System.in);
        String num = input.nextLine();
        String line = input.nextLine();
        String []s = line.split(" ");
        if(Integer.parseInt(num)%2 == 0){
            int preIndex = 0,lastIndex = s.length - 1;
            while (lastIndex %2 == 1 && lastIndex > -1){
                if(lastIndex == 1)
                    System.out.print(s[lastIndex]);
                else System.out.print(s[lastIndex] + " ");
                lastIndex -= 2;
            }
            System.out.print(" ");
            while (preIndex %2 == 0 && preIndex < s.length){
                if(preIndex == s.length - 1 || preIndex == s.length - 2)
                    System.out.print(s[preIndex]);
                else System.out.print(s[preIndex] + " ");
                preIndex += 2;
            }
        }
        else{
            int preIndex = 1,lastIndex = s.length - 1;
            while (lastIndex %2 == 0 && lastIndex > -1){
                if( lastIndex == 0)
                    System.out.print(s[lastIndex]);
                else System.out.print(s[lastIndex] + " ");
                lastIndex -= 2;
            }
            System.out.print(" ");
            while (preIndex %2 == 1 && preIndex < s.length){
                if(preIndex == s.length - 1 || preIndex == s.length - 2)
                    System.out.print(s[preIndex]);
                else System.out.print(s[preIndex] + " ");
                preIndex += 2;
            }
        }

虽然有两个while,但是step是2,也只有一次循环,效率较之前大大提升,也通过case所有用例。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值