编程马拉松 Day01 面试题小记

打算从今天起开始每日一练,巩固一下算法,数据结构相关的知识,废话少说,开始看题。

题目

以上是我近期面试中遇到的一些题,其中1,3题出自百度系面试官;2,4出自Uber系面试官。

两个水杯倒出3L水的问题

先来看第一个问题,题干是要求倒腾出3L的水。我们可以从4、5两个数字入手,观察通过怎样的方式能够得到3,得到以下两种情况

  • 4 * 2 -5 == 3
  • ( 5 - 4 ) * 3 == 3

转换为文字

  1. 第一种方式
    • 先将4L的杯子接满水,全部倒入到5L的杯子中(tips:此时4L的杯子为空,5L的杯子中装载了4L水,还能再倒入1L)
    • 再将4L的杯子接满水,然后向5L的杯子倒水,当5L杯子倒满时,4L杯子剩下3L水
  2. 第二种方式
    • 将5L的杯子接满水,倒入4L的杯子中(tips: 此时5L的杯子剩下1L水),然后将4L杯子的水全部倒掉,再将5L杯子剩余的1L水倒入4L的杯子(tips: 此时4L杯子有1L水)
    • 将5L的杯子接满水,倒入4L的杯子中(tips: 由于上一轮4L杯子已存在1L水,本次5L杯最多只能倒出3L水,倒出后5L杯剩余2L水),然后将4L杯子的水全部的倒掉,再将5L杯子剩余的2L水倒入到4L的杯子(tips: 此时4L杯子有2L水)
    • 将5L的杯子接满水,倒入4L的杯子中(tips: 由于上一轮4L杯子已存在2L水,本次5L杯最多只能倒出2L水,倒出后5L杯正好剩余3L水)

大数四则运算

第二个问题是一个典型的大数运算问题。编程中有时会遇到数字上溢(tips: 如数值的大小超过了Long型可表示的最大数)的问题,此时便需要采用字符串替换原有的数值计算。

以10进制加法为例,解决思路如下:

  1. 使用字符串装载参与计算的两个数值
  2. 分别取两个字符串的末尾数值 a和b,进行相加计算 sum = a+b ,如结果sum大于9,则设置进位标志 flag = 1;否则设置 flag = 0。记录sum%10,表示当前位的结果
  3. 再次取两个字符串的次末尾数值 a和b,进行相加计算 sum = a+b+flag ,如结果sum大于9,则设置进位标志 flag = 1;否则设置 flag = 0。记录sum%10,表示当前位的结果
    ...
  4. 重复以上步骤,若两个数字字符串的长度不一致,则当其中较短字符串s1遍历完成后,只遍历另一个字符串s2,每次取出s2的末位数值与flag相加,得到新的进制标志和当前位的结果。

代码如下:

public static String bigSumAdd(String s1, String s2) {
        StringBuilder stringBuilder = new StringBuilder();//字符串构造器
        int flag = 0;//初始化进位标志
        //判定操作数长度大小
        String longer = s1.length() > s2.length() ? s1 : s2;
        String shorter = s1.length() > s2.length() ? s2 : s1;
        for (int i = 1; i <= longer.length(); i++) {
            int last1 = longer.length() - i ;//取longger最后一位的索引值
            int last2 = shorter.length() - i ;//取shorter最后一位的索引值
            int currentLonger = (int) longer.charAt(last1);
            if (i < shorter.length()) {
                int currentShorter = (int) shorter.charAt(last2);
                //每次charAt()取出的只是char型变量 '1'~'9',需减去'0'方可得到数字1~9。
                int sum = (currentShorter - '0') + (currentLonger - '0') + flag;
                flag = sum > 9 ? 1 : 0;//设置进位标志flag
                stringBuilder.append(sum % 10);//将当前位结果append到stringBuilder中
            } else {
                int sum = currentLonger - '0' + flag;
                flag = sum > 9 ? 1 : 0;
                stringBuilder.append(sum % 10);
            }
        }
        //反转字符串,输出
        return stringBuilder.reverse().toString();
}

字符串去重

这道题比较简单,有多种方法。

先排序再去重,时间复杂度 O(N*LogN)

public static String deDuplicate(String str) {
    char strArr[] = str.toCharArray();//将字符串能转化为字符数组
    Arrays.sort(strArr);//将字符数组排序
    char pre = strArr[0];//取字符数组首位字符
    StringBuffer stringBuffer = new StringBuffer();
    stringBuffer.append(pre);//添加到缓冲中
    for (int i = 1; i < strArr.length; i++) {
        char current = strArr[i];
        if (current == pre) {//判断当前字符与之前字符是否一致,若一致则跳过此次循环
            continue;
        }
        stringBuffer.append(current);//否则将当前字符添加到缓冲中
        pre = current;//将当前字符赋值于pre
    }
    //输出
    return stringBuffer.toString();
}

采用辅助空间,时间复杂度 O(N),空间复杂度与字符串编码集相关

public static String deDuplicate2(String str) {
    int help[] = new int[65536];//65536即2^16,可对应2个字节以内的任意字符
    StringBuffer stringBuffer = new StringBuffer();
    for (int i = 0; i < str.length(); i++) {
        char current = str.charAt(i);//去当前字符
        if (help[current] != 0) {//若当前字符已存在,则跳过本次循环
            continue;
        } else {
            help[current]++;//否则将当前字符对应的位置位非0
            stringBuffer.append(current);//添加到缓冲中
        }
    }
    //输出
    return stringBuffer.toString();
}

杨辉三角

这道题是一个三角问题,观察三角构型,得到如下现象:

  1. 从第一行到第五行,每行依次有1,2,3,4,5个数字...
  2. n行的三角共有 1+2+..+n-1+n 个数字
  3. 每一行的首位及末位数字均为'1',中间数字为正上方左右两个数字的和。

若用一维数组存储三角中的所有数字,从上到下,从左到右开始索引,则从第i行,索引值为index的数值 arr[index] = arr[index - i] + arr[index-i-1],代码如下:

/**
 * 打印杨辉三角
 * @param n 表示杨辉三角的行数
 */
public static void yanhuiTriangle(int n){
    int size = 0;
    //得到一维数组长度
    for (int i = 0; i <= n; i++) {
        size += i;
    }
    int arr[] = new int[size];//创建一维数组
    int index = 0;
    for (int i = 0; i < n; i++) {//外层循环,控制行
        for (int j = 0; j < n - i; j++) {
            System.out.print(" ");//打印数字之前的空格
        }
        for (int j = 0; j <= i; j++) {//内存循环,控制列
            if (j == 0 || j == i) {//每行的首位及末尾
                arr[index] = 1;
            } else {
                arr[index] = arr[index - i] + arr[index - i - 1];//中间位求值
            }
            System.out.print(arr[index] + " ");//打印数值
            index++;
        }
        System.out.println();
    }
}

总结

第一天的开胃菜到此结束,题目本身并不难,更多的是对编程思维的考察,今天先到这里,如有疑问欢迎与我联系 :)

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

推荐阅读更多精彩内容