京东2018校招编程题解答(Java)

写在前面

本篇博客主要是解答这次校招中京东的笔试编程题,这次京东的笔试编程题比较难,涉及KMP算法、manacher算法等。文中的解法也是在观看了左神(左程云)9月20号在牛客网的直播后,自己花时间写出来的。本篇博客不涉及算法的具体分析,主要是解题代码及简单的思路,关于其中的一些算法我会在后面的博客中详细介绍。

题目及解答

题目一

题目描述:
东东从京京那里了解到有一个无限长的数字序列: 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5, ...(数字k在该序列中正好出现k次)。东东想知道这个数字序列的第n项是多少,你能帮帮他么。


输入描述:
输入包括一个整数n(1 ≤ n ≤ $10^{18}$) 。

输出描述:
输出一个整数,即数字序列的第n项。

示例:
输入
169
输出
18

解题思路:
这个主要是等差数列的求和,假设给的输入为k,则
$n(n-1)/2 < k < n(n+1)/2$,化简得到$\frac{1+\sqrt{1+8k}}{2} > 0$,即求上式满足时的最小正整数。同时此题要注意数的范围。

具体代码:

public long findNum(long input){
    return (long)Math.ceil((Math.sqrt(1 + 8 * input) -1)/2);
}

题目二

题目描述:
东东在一本古籍上看到有一种神奇数,如果能够将一个数的数字分成两组,其中一组数字的和等于另一组数字的和,我们就将这个数称为神奇数。例如242就是一个神奇数,我们能够将这个数的数字分成两组,分别是{2,2}以及{4},而且这两组数的和都是4。东东现在需要统计给定区间中有多少个神奇数,即给定区间[l, r],统计这个区间中有多少个神奇数,请你来帮助他。

输入描述:
输入包括一行,,一行中两个整数l和r(1 ≤ l,r ≤ $10^9$,0 ≤ r - l ≤ $10^6$),以空格分割。

输出描述:
输出一个整数,即区间内的神奇数个数。

示例:
输入
1 50
输出
4

解题思路:
这个题主要是判断一个数是不是神奇数,且时间复杂度尽量低。一个数判断神奇数的问题其实是一个背包问题,比如242这个数,就是数组arr[2,2,4]中每个数可以用也可以不用,是否能组成sum(arr) = 8的一半,能则是神奇数,反之则不能。还有如果和为奇数则也不能。

具体代码:

public int findMagicNumber(int start, int end) {
    int ans = 0;
    int[] digitals = new int[10];
    boolean[] dp = new boolean[9 * 9];
    Arrays.fill(digitals, -1);
    Arrays.fill(dp, false);
    dp[0] = true;
    for (int i = start; i <= end; i++) {
        int num = i;
        int sum = 0;
        int index = 0;
        while (num > 0) {
            int temp = num % 10;
        digitals[index++] = temp;
            sum += temp;
            num = num / 10;
        }
        // 当各位数字和为偶数时,才存在神奇数
        if ((sum & 1) == 0){
            for (int j = 0; j < digitals.length && digitals[j] != -1; j++) {
                for (int k = sum; k >= 0; k--) {
                    // 用一维数组进行更新
                        dp[k] = dp[k] || j == 0 ? sum == digitals[j] : (k - digitals[j] < 0 ? false : dp[k-digitals[j]]);
                }
                if(dp[sum / 2]) {
                    ans++;
                    break;
                }
            }
        }
        Arrays.fill(digitals, -1);
        Arrays.fill(dp, false);
        dp[0] = true;
    }
    return ans;
}

题目三

题目描述:
给定一个字符串s,请计算输出含有连续两个s作为子串的最短字符串。注意两个s可能有重叠部分。例如,"ababa"含有两个"aba"。

输入描述:
输入包括一个字符串s,字符串长度length(1 ≤ length ≤ 50),s中每个字符都是小写字母。

输出描述:
输出一个字符串,即含有连续两个s作为子串的最短字符串。

示例:
输入
abracadabra
输出
abracadabracada

解题思路:
这个题目是关于KMP算法中求next数组的问题,我们只需求出字符串最后一个字符后一位的next值。这个能算出来这个题目就解决了。

具体代码:

public String shortestRepeatString(String str){
    int[] next = new int[str.length() + 1];
    Arrays.fill(ne    xt, 0);
    next[0] = -1;
    next[1] = 0;
    for (int i = 2; i < next.length; i++) {
        char pre = str.charAt(i - 1);
        int k = next[i - 1];
        while (k != -1){
            if (str.charAt(k) == pre) {
                next[i] = next[i - 1] + 1;
                break;
            }
            k = next[k];
        }
    }
        
    return str + str.substring(next[str.length()]);
}

题目四

题目描述:
合法的括号匹配序列被定义为:

  1. 空串""是合法的括号序列。
  2. 如果"X"和"Y"是合法的序列,那么"XY"也是一个合法的括号序列。
  3. 如果"X"是一个合法的序列,那么"(X)"也是一个合法的括号序列。
  4. 每个合法的括号序列都可以由上面的规则生成。
    例如"","()","()()()", "(()())","(((())))"都是合法的。 东东现在有一个合法的括号序列s,一次移除操作分为两步:
  5. 移除序列s中第一个左括号。
  6. 移除序列s中任意一个右括号,保证操作之后s还是一个合法的括号序列。

东东现在想知道使用上述的移除操作有多少种方案可以把序列s变为空。

如果两个方案中有一次移除操作移除的是不同的右括号就认为是不同的方案。
例如: s = "()()()()()",输出1,因为每次都只能选择被移除的左括号所相邻的右括号。
s = "(((())))",输出24,第一次有4种情况,第二次有3种情况,... ,依次类推,4 * 3 * 2 * 1 = 24。
输入描述:
输入包括一行,一个合法的括号序列s,序列长度length(2 ≤ length ≤ 20)。

输出描述:
输出一个整数,表示方案数。

示例:
输入
(((())))
输出
24

解题思路:
从右往左遍历,遇到左括号看左括号右边右括号数量与左括号数量的差,并将这些差乘起来,即为方案数。

具体代码:

public int removeSolutions(String str){
    int ans = 1;
    int count = 0;
    for (int i = str.length() - 1; i >= 0; i--) {
        if (str.charAt(i) == ')') {
            count++;
        } else {
            ans *= count;
            count--;
        }
    }
    return ans;
}

题目五

题目描述:
京京和东东是好朋友。东东很喜欢回文。回文是指从前往后读和从后往前读是一样的词语。京京准备给东东一个惊喜,先取定一个字符串s,然后在后面附上0个或者更多个字母形成回文,京京希望这个回文越短越好。请帮助京京计算他能够得到的最短的回文长度。

输入描述:
输入包括一个字符串s,字符串s长度length(1 ≤ length ≤ 50)。

输出描述:
输出一个整数,表示京京能够得到的最短的回文长度。

示例:
输入
abab
输出
5

解题思路:
这个题目主要是manacher(马拉车)算法的变形,主要是要求以最后一个字符结尾的时候的最大回文子串。

具体代码:

public int longestPalindrome(String str){
    int ans = 0;
    // 字符串预处理
    String strend = "$#";
    for (int i = 0; i < str.length(); i++) {
        strend += str.charAt(i);
        strend += "#";
    }
    strend += "@";

    // manacher算法
    int[] radius = new int[strend.length()];
    Arrays.fill(radius, 0);
    int right = 0; //回文最右边界
    int center = 0; //回文中心
    int left = 0;  //回文左边界
    for (int i = 1; i < strend.length(); i++) {
        radius[i] = right > i ? Math.min(radius[2 * center - i], right - i): 1;
        while (strend.charAt(i + radius[i]) == strend.charAt(i - radius[i])) {
            radius[i] += 1;
        }
        if (right < i + radius[i]) {
            right = i + radius[i];
            center = i;
        }
        if(right == strend.length() - 1){
            break;
        }
    }

    return 2*str.length() - (radius[center] * 2 - 1)/2;
}

欢迎大家交流和批评指正!

ps:本文有些公式显示不正确,可以访问京东2018校招编程题解答(Java)

更多文章请访问我的博客

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,029评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,395评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,570评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,535评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,650评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,850评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,006评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,747评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,207评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,536评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,683评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,342评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,964评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,772评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,004评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,401评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,566评论 2 349

推荐阅读更多精彩内容