网易-0820笔试
这应该是今年秋招迄今为止做过最难的笔试
刚开始发卷的时候网络异常,好不容易进去题目没看一分钟又504了,我刷新之后又提示笔试已经在其他地方开始,死活就是进不去,来来回回搞了十几分钟才终于进去。
1、两个正整数a和b,每次操作可以删除a或者b中的一个数位(1234变成124这样),最少多少次能够让a是b的倍数或者b是a的倍数。
暴力dfs或者bfs都可以,用set去重(PS自从上次科大讯飞笔试集合去重没做出来,后期总结了一下方法,上次的美团笔试和这次笔试都用上了)
2、类似长城的数组?要求是数组中的每个数字左右两边的数字相等,并且与它本身不等,每次操作可以将一个数字加1,最少的操作次数。
我记得就给了一个测试用例,其实多写几个就可以发现规律:奇数位下标的数字最后都会变成数组中奇数下标的最大值,偶数也是如此。所以只需要将奇数位置的最大值和偶数位置的最大值找出来,然后每个位置算与其的差值和。
注意这样做只能过66%左右,因为要求是相邻的两个数字不能相等,那么如果奇数位的最大值和偶数位的最大值相等的话,就需要在原先答案的基础上 + (n / 2)。
3、好e?字符串中只有red三个字母,只有形成red或者der这种形式的e可以算作好e(好古怪的名字),每次操作可以修改一个字符,最少的操作次数得到最多的好e。
没什么思路,直接输出0可以过30左右。后面想了一般贪心做法,极端情况下就只有reder(eder|eder|eder...)或者dered(ered|ered|ered...)然后手动创建与输入等长的这种形式的两个字符串,按照匹配程度算最少的操作次数,能够66。
4、统计符合条件的三元组个数。(i,j,k)下标满足i<j<k,并且要求a[i]=a[k]以及a[i]>a[j]。
我的思路是先用map存相同数字的下表Map<Integer, List<Integer>>,然后再遍历map。因为List里面都是值相同的不同下标,所以可以在里面固定i和k。通过i和k的下标遍历符合条件的j。可以过68%左右。
有个剪枝的思路是前一步固定的k找到的所有j,可以在遍历后一个k的时候直接复用,然后当后一个k在找j的时候,就可以直接从上一个k+1的位置开始。可以过78%左右。
举个例子[3 1 3 4 3 4],得到的map应该是{3:{0, 2, 4}, 1: {1}, 4:{3, 5}},从key为3开始找,可以固定i=0, k=2,然后for(int j = i+1; j < k; j++)遍历寻找符合条件的j。然后再下一次固定i=0, k=4,然后j就可以直接从3开始,因为0-2之间符合条件的在上一步已经计算。
这个地方应该还可以再优化,只不过没多少时间了就没管了。