8.27 京东笔试Java开发题解(附题目、思路、复杂度)

第一题

题目

某人只喜欢数字 2, 3, 5这三个数字,如222,333,235这样的。但是12345这样就不是他喜欢的,因为包含了除了2,3,5以外的数字。
现询问这个人喜欢的第n个数字(升序排列的第n个数字)是多少。 n <= 1000;

例如 n 等于 5 时,答案为 23。
因为升序排序依次为 2,3,5,22,23。。。所以第5个数字为23.

思路

把这些数字组织成树的形式。
第一层:2,3,4
第二层:22,23,25,33,32,35,55,52,53
以此类推。
然后找第n个数属于哪一层,是这一层的第几个数。

时间复杂度 O(logn)
空间复杂度 O(1)

/**
 * @author WU Jiahui
 * @date 2020/08/27 18:49
 */
public class Main1 {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();

        int level = 1; // 答案在第几层
        int pow = 3;
        int count = 3;
        while (count < n) {

            level++;
            pow *= 3;
            count += pow;
        }

        int countOfLevel = pow; // 当前层一共有几个数
        int targetOfLevel = level >= 2 ? (n - count + pow) : n; // 答案在当前层的第几个数

        int result = 0; // 答案

        // 在第几层,答案就有几位数
        for (int i = 0; i < level; i++) {
            result *= 10;
            if (targetOfLevel <= (countOfLevel / 3)) {
                result += 2;
            } else if (targetOfLevel <= 2 * (countOfLevel / 3)) {
                result += 3;
                targetOfLevel -= countOfLevel / 3;
            } else {
                result += 5;
                targetOfLevel -= 2 * (countOfLevel / 3);
            }
            countOfLevel /= 3;
        }
        System.out.println(result);
    }
}

第二题

题目

时间限制: 3000MS
内存限制: 589824KB

题目描述
某滚球游戏规则如下:球从入口处(第一层)开始向下滚动,每次可向下滚动一层,直到滚至最下面一层为止。球每次可滚至左下、下方或右下三个方格中的任意一个,每个方格都有一个得分,如下图所示。第1层有1个方格,第2层有3个方格,……,以此类推,第n层有2*n-1个方格。设计一个算法,使得球从入口滚至最下面一层的总得分和最大。
图片说明

输入描述
第1行的正整数n表示数字三角形的层数。(n<=100)

接下来n行包含一个数字三角形,每一行包含2n-1个方格,对应有2n-1个表示得分的正整数(不超过10^5),每两个数字之间用空格隔开。

输出描述
球从入口(第一层)滚至最下面一层的最大得分和。

样例输入
3
1
2 1 2
3 4 2 1 3

样例输出
7

思路

用动态规划,加空间压缩。

时间复杂度:O(n^2)
空间复杂度:O(n)

/**
 * @author WU Jiahui
 * @date 2020/08/27 20:04
 */
public class Main2 {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();

        scanner.nextLine();
        String s = scanner.nextLine().trim();
        // String[] arr = s.split("\\s");
        int[][] dp = new int[2][2 * n - 1];
        dp[0][n - 1] = Integer.parseInt(s);

        int cur = 0;
        int last;
        for (int i = 1; i < n; i++) {
            cur = i % 2;
            last = 1 - cur;

            s = scanner.nextLine().trim();
            String[] arr = s.split("\\s");
            int beginIndex = n - 1 - i;
            // 读当前行的数据
            for (int j = 0; j < arr.length; j++) {
                dp[cur][beginIndex++] = Integer.parseInt(arr[j]);
            }

            beginIndex = n - 1 - i;
            // 更新当前行的路径和
            dp[cur][beginIndex] += dp[last][beginIndex + 1];
            beginIndex ++;
            dp[cur][beginIndex] += Math.max(dp[last][beginIndex], dp[last][beginIndex + 1]);
            beginIndex++;

            for (int j = 2; j < (arr.length - 1); j++) {
                int lastMax = Math.max(dp[last][beginIndex - 1], dp[last][beginIndex]);
                lastMax = Math.max(lastMax, dp[last][beginIndex + 1]);
                dp[cur][beginIndex] += lastMax;
                beginIndex++;
            }

            dp[cur][beginIndex] += dp[last][beginIndex - 1];
        }

        int result = 0;
        for (int j = 0; j < dp[0].length; j++) {
            result = Math.max(result, dp[cur][j]);
        }
        System.out.println(result);
    }
}
#笔经##京东##Java工程师#
全部评论
第一题就是转化成3进制来做就行了。不复杂
3 回复
分享
发布于 2020-08-27 22:45
第二题好像LeetCode上有 不过那是两个方向 我居然忘了如何自下向上动态规划了😂
1 回复
分享
发布于 2020-08-27 22:42
联易融
校招火热招聘中
官网直投
大佬。。
点赞 回复
分享
发布于 2020-08-27 22:09
觉得第一题用一个队列来做比较简单
点赞 回复
分享
发布于 2020-08-27 23:12
为什么我的第一题和你们不太一样,题目要求是如果是素数的话,只要包含2、3、5任意一个就满足要求,比如13;或者是只包含2、3、5三个数字,例如22、33。最后我按照这个要求也是全通过的😂
点赞 回复
分享
发布于 2020-08-31 17:02
喜欢的数字一定是个位数吗?
点赞 回复
分享
发布于 2020-09-17 12:55
第一题这个思路好难想啊。。很巧妙
点赞 回复
分享
发布于 2021-10-09 17:31

相关推荐

4 22 评论
分享
牛客网
牛客企业服务