Java数组考题,java面试中常见的数组题目汇总(一)

96b13e1cc53509f3fec840a8b8827444.png

题目难度:* *

(学习视频推荐:java课程)

1、排序次序

【题目】

返回一个数字数组的排序值,比如数据 [6,2,5,0] 的返回是 [4,2,3,1]

【代码】package swear2offer.array;

import java.util.Arrays;

public class SortSequence {

/**

* 返回一个数字数组的排序值

* 比如数据 [6,2,5,0] 的返回是 [4,2,3,1]

* */

public int[] compare(int[] a) {

int i,j,n;

n = a.length;

int [] c = new int[n];

//数组下标从0开始,但是输出的次序从1开始,所以需要初始化数组为1

for (i=0; i

c[i]++;

}

for (i=0; i

for (j=0; j

if (a[j]

else c[j]++;

}

}

return c;

}

public static void main(String[] args) {

int[] a = {6,2,5,0};

System.out.println(Arrays.toString(new SortSequence().compare(a)));

}

}

【思考】

正常的获得次序的方式是每一个元素都与其他所有元素进行比较,然后获得大小次序,但是这里采用的是梯形比较次序6

6 2

6 2 5

6 2 5 0

比较的时候,不仅判断比较元素,同时也判断被比较元素,也就是if else的代码,这样可以减少比较次数。

2、数组下标辅助记录

【题目】

给定一个数组 a, 长度为 N, 元素取值范围为 [1, N],统计各个元素出现的次数,要求时间复杂度为 O (N), 空间复杂度为 O (1)

【代码】/**

* 这类要求空间O(1)时间复杂度为O(n)的问题

* 需要在一次遍历并且不声明新数组的情况下求解,这种题目通常要求元素大小跟下标大小一致。

* 所以通常考虑是利用数组存储的元素和数组下标来求解

* 在本题中,数组的元素变成了下标,而数组内元素则表示之前元素出现的次数,0则代表不出现。

* 为了区分元素和次数,可以把次数设定为负值

* */

public void Solution(int[] a) {

int i,n,temp;

n = a.length;

i = 0;

/**

* 只有在temp小于0的时候才会推进循环

* */

while(i < n) {

temp = a[i]-1;

// 如果数组元素小于0,则代表该数已经被替换到其他地方或者已经被计数过从而被覆盖

if (temp < 0) {

i ++;

continue;

}

// 把未记录的数保存在已经记录的位置上,并用负值保存数量

if (a[temp]>0) {

a[i] = a[temp];

a[temp] = -1;

} else {

a[i] = 0; //该数据已经使用过,且表示元素i+1出现0次

a[temp]--;

}

}

}

3、查找有序二维数组的元素

【题目】

在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

【代码】package swear2offer.array;

public class ArrayFind {

/**

* 在一个二维数组中(每个一维数组的长度相同),

* 每一行都按照从左到右递增的顺序排序,

* 每一列都按照从上到下递增的顺序排序。

* 请完成一个函数,输入这样的一个二维数组和一个整数,

* 判断数组中是否含有该整数。

*

* 思路:

* 从左上出发,需要考虑的情况太多,因为向右和向下都是递增

* 但是从右上出发,向左递减,向下递增,这样就把情况限定在一种。

* */

public boolean Find(int target, int [][] array) {

int l,h,x,y;

h = array.length;

l = array[0].length;

// 游标的横纵坐标

x = l-1;

y = 0;

while (x>=0 && y

if(array[y][x] == target) {

return true;

}

if (array[y][x]

y++;

} else {

x--;

}

}

return false;

}

public static void main(String[] args) {

int[][] a = {{1,3,5,6},{2,4,7,8},{5,8,9,12}};

System.out.println(new ArrayFind().Find(11,a));

}

}

【思考】

从左上出发,需要考虑的情况太多,因为向右和向下都是递增,但是从右上出发,向左递减,向下递增,这样就把情况限定在一种。特殊的数组,充分利用数组的特殊性,从不同的方向考虑方法。

4、跳台阶

【题目】

一只青蛙一次可以跳上 1 级台阶,也可以跳上 2 级。求该青蛙跳上一个 n 级的台阶总共有多少种跳法(先后次序不同算不同的结果)。

【代码】package swear2offer.array;

public class Floors {

/**

* 一只青蛙一次可以跳上 1 级台阶,也可以跳上 2 级。

* 求该青蛙跳上一个 n 级的台阶总共有多少种跳法(先后次序不同算不同的结果)。

*

* 获取跳法次数

* */

public int JumpFloor(int target) {

if (target < 3) return target;

// 大于等于3个台阶,次数是第一步调1下和跳2下的个数之和

return JumpFloor(target-1) + JumpFloor(target-2);

}

}

5、变态跳台阶

【题目】

一只青蛙一次可以跳上 1 级台阶,也可以跳上 2 级…… 它也可以跳上 n 级。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。

【代码】package swear2offer.array;

import java.util.Arrays;

public class FloorsPlus {

/**

* 一只青蛙一次可以跳上 1 级台阶,

* 也可以跳上 2 级…… 它也可以跳上 n 级。

* 求该青蛙跳上一个 n 级的台阶总共有多少种跳法。

*

* 动态规划:数组代表含义、边界、转换公式

* 动态规划最重要的是找出阶段之间的变化公式,

* 即,n-1和n之间的状态是如何转移的

*

* f[n]:n阶台阶的跳法

* f[n] = f[n-1]+f[n-2]+...+f[1]+f[0]

* f[n-1]代表最后一步走了1步

* f[n-2]代表最后一步走了2步

* f[1]代表最后一步走了n-1步

* f[0]代表最后一步走了n步

*

* 这里需要注意,f[0]=0,但是最后一步走了n步也算一种方法,

* 所以需要初始化把数组初始化为1,或则单独处理f[0].

*

* */

public int JumpFloorII(int target) {

if (target < 3) return target;

int[] f = new int[target+1];

//单独处理f[0]

f[0] = 1;

f[1] = 1;//边界

int i,j;

for (i=2; i<=target; i++) {

for (j=i-1; j>=0; j--) {

f[i] += f[j];

}

}

return f[target];

}

public int JumpFloorII2(int target) {

if (target < 3) return target;

int[] f = new int[target+1];

//初始化把数组初始化为1

Arrays.fill(f,1);

f[0] = 0;

f[1] = 1;//边界

int i,j;

for (i=2; i<=target; i++) {

for (j=i-1; j>0; j--) {

f[i] += f[j];

}

}

return f[target];

}

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值