面试小记-3-等概率输出10000内数字等4道算法题

前两天面了家单位,面试题就1页纸,虽然写着iOS试题,但没有任何跟oc相关的东西,竟然是4道算法题1道小学(初中?)算火车相遇次数的应用题。一看是这样的题目布局就知道自己要歇菜,但没关系来刷刷题也好,毕竟也刷过leet了。不多说先赶紧拍张题目照片先。。。

回来后网上搜了下这几个题目,都没有搜到出处,所以不知道答案。以下解答是自己的理解,也许会有错误,仅供参考。


1、给出已实现函数int rand100()可以等概率输出0~99数字,现在要求根据此函数实现int rand10000()等概率输出0~9999数字(不能用系统随机函数);

答:既然rand100可随机了,直接a = rand100() * 100得出随机千位和百位,再b = rand100()得出随机十位和个位,返回a+b就行。(但之后面试官看了似乎有些不解和不悦,因为我的解法是在生成随机数的时候用了2个rand100组合出来的,所以随机性不是由单个rand100控制。也许题意是希望对rand100做处理只用一个随机函数来生成1w内的随机数)


2、汤姆家要请客会来很多人,但筷子太多而且长短不一,为了让每位客人拿到长短相同的筷子才行,所以请计算汤姆最多能请多少个客人(实现int getMax(int array[N]))。

答:筷子嘛,要成双成对。所以我先将数组排序,然后遍历数组找出相邻位置值相同的个数就行。由于要排序,所以为了节省试卷版面不想写排序算法我就用文字写了逻辑,但面试官抱怨为何不写代码(所以这面试还真是,有的人我拿起笔准备写代码他立马别别别说下逻辑就行,有的人又抱怨无码)。然后我解释了下代码逻辑,半天后他说没听明白然后判定我写错,我也没争辩,反正不抱希望也就没必要多费口舌了。回来后自己按逻辑实现代码,测了下应该没错,当然前提是我理解的题目意思无误才行,否则代码也是错的。

另:返回来看了看,觉得都懒得用排序了,直接暴力对比,类似冒泡的方法,将相等的一对置为-1,再一个个比较,代码不长,随便测了几个没问题,贴上来备案。

如下:

int tomsChopstick(int num[], int numSize) {
    int result = 0;
    
    for (int i = 0; i < numSize; i++) {
        for (int j = i + 1; j < numSize - 1 && num[i] != -1; j++) {
            if (num[i] == num[j]) {
                num[i] = -1, num[j] = -1;
                result++;
                break;
            }
        }
    }
    
    return result;
}


3、给定一个数组,可以任意交换2个元素位置形成一个新数组,求一共能得出多少个新数组,注意[3,3,3,3]无论如何调换位置都只是一个数组。

答:这不是跟leet上求电话号码组合那道题有点像么,类似深搜,但要判断相同数字。我的基本逻辑是深搜,设定一个int level标示当前要交换元素的底标,设定一个int index标示活动元素底标,则a[0](level标示)跟之后每一个元素(index表示)交换位置组成新数组,到底后变为a[1]再每个交换位置看是否是新数组,直到level到底。这道题倒是写了代码,但留白处太少写的较密,面试官说看得头疼也没看明白问我递归要干嘛,我也没怎么解释因为觉得没必要了。一张比a4还稍小的纸,出了5道题,题目还有图都占了一般空白了,剩下的留白再平分给5道题写代码,那也别怪我写得密。当然也有可能是故意为之,因为要筛选能把一行代码写出n种执行逻辑的牛人。这题回来后没写代码,因为觉得没有完整用例写了也不知对不对。

另:返回来看了看,突然觉得这么简单的问题当时怎么就发懵了呢,看到的题都不自主的往leet上靠,现在静下心来看看觉得比leet的easy题都简单,但现场就是晕了。根本用不着递归,就直接比较2个数字是否相同,不同则是新的相同则略过就行了,代码也简单,不过用例不多不知道测试对不对。

如下:

int nCountOfArray(int *num,  int numSize) {
    int result = 0;
    
    for (int i = 0; i < numSize; i++) {
        for (int j = i; j < numSize - 1; j++) {
            if (num[i] != num[j + 1]) {
                for (int x = 0; x < numSize; x++) {
                    if (x == i)
                        printf("%d ", num[j + 1]);
                    else if (x == j + 1)
                        printf("%d ", num[i]);
                    else
                        printf("%d ", num[x]);
                }
                result++;
                printf("\n");
            }
        }
    }
    
    return result;
}


4、给出二维数组array[M][N],要求反斜线方向打印元素(从右上-->左下)。

答:这题我写的还是类似深搜的算法:先实现一个从右上到左下的打印逻辑print(),然后一个for循环以第一行作为首元素循环调用print()(回来后在机器上run了一下,当for循环到第一列最后一个元素后a[0][n-1],在判断要从该元素下一层位置a[1][n-1]打印时逻辑有误打印错误)。这道题也写满了代码,面试官说你第二题都不对这第四题也不用看了,这第四题我就没见人写对过。咦我凑,第二题我的不对吗,行吧你说不对就不对吧。这第四题我也觉得确实没写对,不看也罢,反正大家都错了。

另:后来返回来看见这题就顺便清了,根本用不着深搜,逻辑很清晰就看编程基本功了,无压力下20多分钟写出来编译出越界错误,小改一下,测了几个用例应该没错。所以说面试的时候有压力了一紧张思路可能就乱了,其实这道题还是简单的,至少比leet的那个z字形打印字符串的题目简单吧,而且那题还是easy的。。。话又说回来,一般面试的程序题代码量应该都不大的,要不然怎么可能让面试者短时间内写完呢是吧。

如下:

void inclinePrint(int **martix, int row, int column) {
    int drow = 0, dcolumn = 0;
    
    for (int i = 0; i < column; i++) {
        drow = 0, dcolumn = i;
        
        while (dcolumn >= 0 && drow < row) {
            printf("%d ", martix[drow][dcolumn]);
            drow++, dcolumn--;
        }
        printf("\n");
    }
    
    for (int i = 1; i < row; i++) {
        drow = i, dcolumn = column - 1;
        
        while (drow < row && dcolumn >= 0) {
            printf("%d ", martix[drow][dcolumn]);
            drow++, dcolumn--;
        }
        printf("\n");
    }
}


5、北京开往上海的火车x全程13.5小时能到,上海开往北京的火车y全程15.5小时能到。现在有一个乘客A坐在1辆火车上从北京开往上海,同时有1辆火车从上海开往北京,其中每隔1小时都有1辆火车从上海开往北京。求在A到达上海的过程中能看见几辆从上海开往北京的火车。

答:这道题是我花费最长时间的一题,比编程还难。。。我的逻辑是算出x、y第一次相遇的时间t1,然后13.5-t1计算x剩余时间,然后计算y的1小时距离内x、y相遇时间t2,然后t1/t2再加1就是n,最后得出15。最后面试官说答案是29,那有可能是过程中哪里多除了个2。

虽然面试过程不算愉快,不过总的来说题目还是考验人的,公司也不错是做广电的应该是国企下属的互联网事业部,招的也都要求211以上。聊的时候了解到iOS岗位主要做手机电视客户端的优化和提升用户体验,app上线都已经3年多了,那就能理解为何题目全是算法题了,因为要的是算法牛人来优化和提升的,自己肯定不行啊。于是面试官问我还有什么其他问题时我很知趣的说没有了,最后在我的个人问题上闹了个小笑话,大家相视大笑也算缓解了面试不利那压抑的气氛,其实面试官人还是不错的,只是自己不达标准别人也没必要给笑脸而已。

以上。


返回来重新看了看编程题,发现考查的基本都是双重循环的东西,没有什么高深的算法题,还是挺基本的,无奈当时自己现场生生往leet上靠,导致想得复杂了,现在一写觉得实在简单,怪不得当时我记得还有一面试的哥们,大概不到40分钟吧就写完了,觉得很牛叉啊,现在看来还真是差不多。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值