8.2号 shopee提前批 Java工程师 笔试题

2.1 shopee提前批笔试-8.2

2.1.1 编程一:动态规划

数的划分,将整数n分成k份,且每份不能为空,任意两种划分方案不能相同

思考:方案数,最大值,不能穷举,极大可能是动态规划。

1、涉及到两个变量 n和k 所以应该是需要二维数组,dp [i] [j]

2、dp [i] [j] 代表 i 个数分成 j 份

3、怎么分解 dp [i] [j]?

  • 拿到一个整数 i ,因为题目中要求每份不能为空,因此必须先拿出 j 个数位将 j 份分别放上1,此时剩下 i - j个数。
  • 那么剩下的数如何处理呢?可以将其全部分到一份当中(dp[i-j] [1]),也可以分到两份中(dp[i-j] [2]),…,也可以分到 j 份中(dp[i-j] [j]),而每一种分法都是不相同的,所以可以将其全部加起来,和即为dp[i] [j]。
  • 这里其实就已经去重了,因为分到两份去,并没有指定是那两份,所以根本没关系,只加了一次。

在这里插入图片描述
4、到这里已经可以写了,但是跟我们平常的状态方程不一样,尝试化简

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qSrTv2j1-1631689582592)(秋招笔试真题.assets/20190118140728870.png)]
5、两个式子一起化简得,即为本题状态转移方程,直接还真不好想?

在这里插入图片描述
6、遍历的方向,只知道基线是0个数字分成0个分发是一种,其他没有已知条件,正向遍历。

总结:

1、尝试dp[i-1] [j-1]、dp[i] [j-1] 、dp[i-1] [j] 这三部分来推导 dp[i] [j]

2、如果不行,能不能考虑缩小问题的范围方向

	// 输入:两个整数n,k(6<n<=200,2<=k<=6)。
	// 输出一个整数,即有几种不同的分法。
    public int  divide(int n,int k){
        if(n==0|| k==0) return 0;
        int[][] dp = new int[n+1][k+1];
        dp[0][0] = 1;
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= k; j++) {
                //划分的份数不能超过给定的整数,既满足不能为空的条件
                if(i>=j){
                    dp[i][j] = dp[i-j][j]+dp[i-1][j-1];
                }
            }
        }
        return dp[n][k];
    }

2.1.2 编程二:二分法

一个数组,找到一个数的下标,该数左边的所有数和 与右边的所有数和相同。若有多个,返回第一个

思路一:从头到尾遍历数组,计算左边之和,右边之和,比较它们。

思路二:双指针,首尾遍历,根据和来判断是左移还是右移

思路三:二分法,如果左边的值*2=数组的和-当前位置的值,那么就可以说找到了,如果大于,那就向前移动,小于就向后移动。

// 二分法
public int findBalancedIndex(int[] arr){
        if(arr==null || arr.length==0) return -1;
        int left = 0,right = arr.length-1;

        int total = 0;
        for (int i = 0; i < arr.length; i++) {
            total+=arr[i];
        }
        while(left<right){
            int mid = left+ (right-left)/2;
            int leftTotal = 0;
            for (int i = 0; i < mid; i++) {
                leftTotal+=arr[i];
            }
            if(leftTotal*2==total-arr[mid]) return mid;
            else if(leftTotal*2<total-arr[mid]) left = mid;
            else  right = mid;
        }
        return -1;
    }

//暴力求解
    public int findBalancedIndex(int[] inputArray) {
        int sum = 0;
        for (int i : inputArray) {
            sum += i;
        }

        int sum2 = 0;
        for (int i = 0; i < inputArray.length; i++) {
            if (sum2 * 2 + inputArray[i] == sum) {
                return i;
            }

            sum2 += inputArray[i];
        }

        return -1;
    }

2.1.3 编程三:栈+状态机

XML解析。

<people><name>shopee</name></people> ,输入people.name返回shopee,输入people.age返回 “ ”

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值