搜狗三道编程题整理(2020/09/05)

备战秋招面试 微信搜索公众号【TechGuide】关注更多新鲜好文和互联网大厂的笔经面经。
作者@TechGuide
点赞再看,养成习惯,您动动手指对原创作者意义非凡🤝

第一题,汪仔换道具,主要思路就是先减去直接换的,然后排序,此时a=0,分为两种情况,b,c给a,以及c给b和a。设x解方程就可以求出表达式

方法一:

作者:千草幽幽
链接:https://www.nowcoder.com/discuss/500293?type=0&order=0&pos=7&page=1&channel=666&source_id=discuss_center_0
来源:牛客网

class Solution:
    def numberofprize(self , a , b , c ):
        # write code here
        res = 0
        res+= min(a,b,c)
        a -= res
        b -= res
        c -= res
        a,b,c = sorted([a,b,c])
         
        return min(res + (2*b+c)//5,res + (b+c)//4)

方法二:

作者:neebie
链接:https://www.nowcoder.com/discuss/500271?type=all&order=time&pos=&page=1&channel=666&source_id=search_all
来源:牛客网
public int numberofprize (int a, int b, int c) {
        // write code here
        int left=min(a,b,c);
        int right=max(a,b,c);
        while (left<=right){
            int mid=left+(right-left)/2;
            if (check(mid,a,b,c)){
                left=mid+1;
            }else{
                right=mid-1;
            }
        }
        return right;
    }

    private boolean check(int mid, int a, int b, int c) {
        long left=0;
        if (a>=mid){
            left+=(a-mid);
        }else {
            left-=(2*(mid-a));
        }
        if (b>=mid){
            left+=(b-mid);
        }else {
            left-=(2*(mid-b));
        }
        if (c>mid){
            left+=(c-mid);
        }else {
            left-=(2*(mid-c));
        }
        return left>=0;
    }

    private int min(int a, int b, int c) {
        return Math.min(Math.min(a,b),c);
    }
    private int max(int a, int b, int c) {
        return Math.max(Math.max(a,b),c);
    }

第二题,建房子,思路是找房子间隔,大于t就+2,等于t就+1,最后考虑最左和最右,+2就可以了

class Solution:
    def getHouses(self , t , xa ):
        # write code here
        res = 0
        for i in range(0,len(xa),2):
            xa[i],xa[i+1] = xa[i]-xa[i+1]/2,xa[i]+xa[i+1]/2
        for i in range(len(xa)//2 -1):
            if xa[2*i+2] - xa[2*i+1] == t:
                res += 1
            elif xa[2*i+2] - xa[2*i+1] > t:
                res += 2
        return res+2

方法二:

public int getHouses (int t, int[] xa) {
        // write code here
        if (xa==null||xa.length==0)
            return 0;
        double[][] xAndA=new double[xa.length/2][2];
        int idx=0;
        for (int i = 0; i < xa.length; i+=2) {
            xAndA[idx][0]=(double)xa[i]-(double) xa[i+1]/2;
            xAndA[idx][1]=(double)xa[i]+(double) xa[i+1]/2;
            idx++;
        }
        int count=2;
        for (int i = 0; i < xAndA.length-1; i++) {
            if ((xAndA[i+1][0]-xAndA[i][1])==t){
                count++;
            }else if  ((xAndA[i+1][0]-xAndA[i][1])>t){
                count+=2;
            }
        }
        return count;
    }

第三题 求方差和最小的idx,这个题是原题= =有舍友阿里被问过。方法就是D(x) = E(X^2) - E(X)2,利用前缀和数组,可以很快计算出arr[i:j]的E(X)2和E(X^2).

class Solution:
    def find_best_cut(self , arr ):
        # write code here
        n = len(arr)
        prex = [0]
        prex2 = [0]
        for num in arr:
            prex.append(prex[-1]+num)
            prex2.append(prex2[-1]+num**2)
        def var(i,j):
            if i>=j:return 0
            n = j-i+1
            Ex = (prex[j+1]-prex[i])/n
            Ex2 = (prex2[j+1]-prex2[i])/n
            return Ex2-Ex**2
        v = float('inf')
        res = 0
        for i in range(0,n):
            temp = abs(var(0,i-1) + var(i,n-1))
            if temp < v:
                res = i
                v = temp
        return res

方法二:

public long getPasswordCount (String password) {
        // write code here
        if (password.length()==1)
            return 9;
        int i[]=new int[1];
        Deque<Character> stack=new ArrayDeque<>();
        backTrack(password.toCharArray(),0,i,stack);
        return i[0];
    }

    private void backTrack(char[] chars, int start, int[] i, Deque<Character> stack) {
        if (stack.size()==chars.length){
            if (!checkEquals(stack,chars)){
                i[0]++;
            }
            return;
        }
        if (start==0){
            for (int j = 0; j <=9; j++) {
                stack.addLast((char)('0'+(j-0)));
                backTrack(chars,start+1,i,stack);
                stack.pollLast();
            }
        }else{
            int cur=((chars[start]-'0')+(stack.peekLast()-'0'));
            if (cur%2==0){
                stack.addLast((char)('0'+(cur/2-0)));
                backTrack(chars,start+1,i,stack);
                stack.pollLast();
            }else{
                for (int j = 0; j < 2; j++) {
                    stack.addLast((char)('0'+(cur/2+j-0)));
                    backTrack(chars,start+1,i,stack);
                    stack.pollLast();
                }
            }
        }

    }

    private boolean checkEquals(Deque<Character> stack, char[] chars) {
        int idx=0;
        for (Character c:stack){
            if (c!=chars[idx++])
                return false;
        }
        return true;
    }
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值