您的位置:首页 > 其它

网易内推笔试算法题目(1)

2017-08-17 11:20 302 查看
题目描述:

时间限制:2秒

空间限制:32768K

小有一个长度为n的整数序列,a_1,...,a_n。然后考虑在一个空序列b上进行n次以下操作:

1、将a_i放入b序列的末尾

2、逆置b序列

小易需要你计算输出操作n次之后的b序列。 
输入描述:
输入包括两行,第一行包括一个整数n(2 ≤ n ≤ 2*10^5),即序列的长度。
第二行包括n个整数a_i(1 ≤ a_i ≤ 10^9),即序列a中的每个整数,以空格分割。

输出描述:
在一行中输出操作n次之后的b序列,以空格分割,行末无空格。

输入例子1:
4
1 2 3 4

输出例子1:
4 2 1 3


题目不做过多解释,很容易理解。接下来主要分析一下阶梯思路,阶梯思路最重要:

通过一个具体用例分析:

// 1 1
// 12 21
// 213 312
// 3124 4213
// 42135 53124
// 531246 642135不难发现,每次跨个一步就可以抵消一次反转。所以我们可以选择1,3,5,7..这种奇数方案求解,如果给的用例是偶数的话,我们可以将用例却去掉最后一个元素当做奇数个用例进行处理,最后将去掉的那个元素单独处理,实现算法如下:

public static String get(int[] nums) {
sb.delete(0, sb.length());//清空StringBuilder,sb是一个静态的全局变量,优化每一次创建对象开销
int n = nums.length;
boolean flag = false;
if (n % 2 == 0) {
n = n - 1;
flag = true;
}

sb.append(nums[0]).append("");
for (int i = 1; i < n - 1; i = i + 2) {
sb.append(" ").append(nums[i]);
sb.insert(0, nums[i + 1] + " ");
}

if ((n + 1) % 2 == 0 && flag) {//处理偶数个元素的时候,丢掉的那个元素单独处理
sb.append(" ").append(nums[nums.length - 1]);
sb.reverse();//偶数最后一个元素需要反转一下,找个具体用例就可以验证
}

return sb.toString();
}

兴高采烈的提交了,结果才通过百分之40的case,此刻只能想着继续优化了。通过排除上面代码分析,应该是偶数元素单独处理时候的反转浪费空间,所以思路是优化此处,优化思路是:在上面算法中,sb的第一次初始值是nums[0],如果我们用例元素是偶数个时候,我们将初始值设置为sb.append(nums[1]).append(" ").append(nums[0]);的话就可以转为奇数个元素了,这样就可以不需要使用反转了。实现代码:
public static String get1(int[] nums) {
sb.delete(0, sb.length());

int n = nums.length;
boolean flag = false;
if (n % 2 == 0) {
flag = true;
}
int index = 0;
if (flag) {
sb.append(nums[1]).append(" ").append(nums[0]);
index = 2;
} else {

sb.append(nums[0]).append("");
index = 1;
}

for (; index < n - 1; index = index + 2) {
sb.append(" ").append(nums[index]);
sb.insert(0, nums[index + 1] + " ");
}

return sb.toString();
}提交之后吗,测试用例:百分之50 !还是复杂度高,空间超限,所以还要继续优化,思前想后可以优化的就是不再使用StringBuilder,结果再次分析具体用例的输出结果发现:
// 1
// 2 1
// 3 1 2
// 4 2 1 3
// 5 3 1 2 4
// 6 4 2 1 3 5
// 7 5 3 1 2 4 6如果是奇数个元素的话,输出结果的前面半段都是奇数位置的元素输出,然后再试偶数输出,偶数个元素情况类似。按照这个思路的话,我们就可以不在使用StringBuilder保存最终的结果了,而是逐渐打印输出,最终实现代码:
import java.util.Scanner;

public class Main1 {

public static void main(String[] args) {

Scanner cin = new Scanner(System.in);
int size = cin.nextInt();
int[] nums = new int[size];
for (int i = 0; i < size; i++) {
nums[i] = cin.nextInt();
}

get2(nums);
}

public static void get2(int[] nums) {
int n = nums.length;
//便于测试,由于空格不可见,所以调试时候可以使用*替代空格
String space =" ";
if (n % 2 == 0) {

for (int i = n - 1; i > 0; i = i - 2) {
System.out.print(nums[i] + space);
}
// 1 2 3 4 5
for (int i = 0; i < n; i = i + 2) {
System.out.print(nums[i]);
if (i != n - 2) {
System.out.print(space);
}
}

} else {
for (int i = n - 1; i >= 0; i = i - 2) {
System.out.print(nums[i] + space);
}
// 1 2 3 4 5
for (int i = 1; i < n; i = i + 2) {
System.out.print(nums[i]);
if (i != n - 2) {
System.out.print(space);
}
}

}

}

}

百分之百的用例通过!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: