2020年学而思春招算法题

今天学弟分享了一下学而思2020年春招算法题,整理一下,希望对有需要的小伙伴有帮助

斐波那契数列题干思路代码数组问题题干思路代码

斐波那契数列

题干

  有一对兔子,3个月后,每个月都会生一对兔子,生下的兔子过了3个月,也会每月生一对兔子,假设兔子不会死亡,n个月后总共有多少兔子?

思路

  这道题我们可以首先列一下前几个月的兔子数,找一下有没有什么规律。


  可以看到这是一个斐波那契数列,这里给出两种解法,分别是递归法,和动态规划法。(这里建议使用动态规划法,递归法存在大量的重复计算,即f(5) = f(4) + f(3),但是f(4),f(3)在之前的运算中就已经计算过了,此时是重复计算)

 

代码

递归法:

1public int function(int n){
2    if(n == 1 || n == 2){
3        return 1;
4    }
5    return function(n - 1) + function(n - 2);
6}

动态规划法:

 1public int function(int n){
2    if(n <= 2){
3        return 1;
4    }
5    int pre1 = 1;
6    int pre2 = 2;
7    for(int i = 3;i <=n; i++){
8        int cur = pre1 + pre2;
9        pre1 = pre2;
10        pre2 = cur;
11    }
12    return pre1;
13}

数组问题

题干

  输入一个升序数组和一个整数,如果这个数在数组里则返回下标,不在数组里面,就插入到数组,然后返回下标。

思路

  这道题就比较有意思了,解法有很多种,java中的数组不支持动态扩容,所以需要我们去写扩容和数据搬移的逻辑,这里首先先给出一个取巧的办法,我们可以把数组放到ArrayList里,然后利用ArrayList支持动态扩容的特性,来解决这个问题(方法1)。当然我们也可以手写这部分逻辑(方法2)

代码

方法1:

 1public class Main {
2    private int position;
3
4    private Integer[] getOrInsertElement(Integer[] arr, int target) {
5        List<Integer> list = new ArrayList<>(Arrays.asList(arr));
6        for (int i = 0; i < list.size(); i++) {
7            if(list.get(i) <= target){
8                position = i;
9            }
10        }
11        if(list.get(position) != target){
12            position++;
13            list.add(position,target);
14        }
15        Integer[] newArr = new Integer[list.size()];
16        return list.toArray(newArr);
17    }
18}

方法2:

 1public class Main {
2
3    private int position;
4
5    private int[] getOrInsertElement(int[] arr, int target) {
6        // 输入校验
7        if (arr == null || arr.length == 0) {
8            throw new RuntimeException("输入数据非法!");
9        }
10        int max = arr[arr.length - 1];
11        // 扩容位置在数组末尾
12        if (target > max) {
13            return insertTargetElement(arr, target, arr.length - 1);
14        }
15        //查询数组中,小于等于target的第一个位置
16        int pos = getMinOrEqualsTargetPosition(arr, target);
17        if (arr[pos] == target) {
18            this.position = pos;
19            return arr;
20        }
21        return insertTargetElement(arr, target, pos);
22    }
23
24    private int[] insertTargetElement(int[] arr, int target, int pos) {
25        // 扩容
26        int[] newArr = Arrays.copyOf(arr, arr.length + 1);
27        // 数据搬运
28        System.arraycopy(arr, pos, newArr, pos + 1, arr.length - pos);
29        newArr[pos + 1] = target;
30        this.position = pos + 1;
31        return newArr;
32    }
33
34    private int getMinOrEqualsTargetPosition(int[] arr, int target) {
35        int i = 0;
36        int j = arr.length - 1;
37        int result = 0;
38        while (i <= j) {
39            int mid = i + ((j - i) >> 1);
40            if (arr[mid] < target) {
41                i = mid + 1;
42                result = mid;
43            } else if (arr[mid] > target) {
44                j = mid - 1;
45            } else {
46                return mid;
47            }
48        }
49        return result;
50    }
51}

测试代码:

1public static void main(String[] args) {
2    int[] arr = {14567810};
3    Main main = new Main();
4    int[] newArr = main.getOrInsertElement(arr, 11);
5    System.out.println("原数组:" + Arrays.toString(arr));
6    System.out.println("目标值下标:" + main.position);
7    System.out.println("扩容后的数组:" + Arrays.toString(newArr));
8}

  最后,期待您的订阅和点赞,专栏每周都会更新,希望可以和您一起进步,同时也期待您的批评与指正!

posted @ 2020-03-18 22:09  进击的李同学  阅读(512)  评论(0编辑  收藏  举报