0918字节跳动后端笔试情况及代码(AK)

等12点笔试结束后更新代码

第一题

堆金字塔,每块石头长1m,宽1m,按cm计算,给你金字塔的高度n层,然后从1-n给你n个列表,每个列表代表第i层的石头放的位置,如果一个石头左右两边都有石头垫着,或者中心点下面有别的石头,就能稳定,否则就会掉落,上方依赖他的石头也会跟着掉落,问最终只剩下几个石头。
思路:
模拟,因为本身有序,每层的石头掉落情况是依赖于他底下一层石头的剩余情况,按层判断每个石头是否会掉落,用一个新列表存,而不是用老列表删除(有坑,会超时)。
代码:
import java.util.*;

/*
输入:
3
2 100 280
2 190 360
2 150 360
输出:
4

输入:
5
5 0 1000 2000 3010 3200
4 40 1050 2049 3100
1 80
1 120
1 160
输出:
10
 */
public class Q1 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        List<List<Integer>> blocks = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            int cnt = sc.nextInt();
            ArrayList<Integer> list = new ArrayList<>();
            for (int j = 0; j < cnt; j++) {
                list.add(sc.nextInt());
            }
            blocks.add(list);
        }
        int ans = blocks.isEmpty()?0:blocks.get(0).size();
        for (int i = 1; i < blocks.size(); i++) {
            //顺序查找
            List<Integer> newList = new ArrayList<>();
            List<Integer> down = blocks.get(i-1);
            int downIdx = 0;
            Iterator<Integer> it = blocks.get(i).iterator();
            while (it.hasNext() && downIdx < down.size()) {
                Integer left = it.next();
                //找到第一块有接触的石块
                while(downIdx < down.size() && down.get(downIdx)+100 <= left) {
                    downIdx++;
                }
                if(downIdx >= down.size()) {
                    break;
                }
                //保持中心
                else if((down.get(downIdx)<left+50 && down.get(downIdx)+100 > left+50)) {
                    newList.add(left);
                    ans++;
                }
                //保持两边
                else if(down.get(downIdx)+100 <= left+100 && downIdx+1 < down.size() && down.get(downIdx+1)<left+100 ) {
                    newList.add(left);
                    ans++;
                }
            }
            blocks.set(i,newList);
        }
        System.out.println(ans);
    }
}


第二题

字符串中只有01,判断一个“好串”的最大长度(我忘了叫什么名字了)
好串定义:长度大于3,相邻字符不等
思路:
贪心,类似滑动窗口,On。
代码:
import java.util.Scanner;

/*
输入:0101011101
输出:6
 */
public class Q2 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String str = sc.nextLine();
        int left = 0;
        int ans = 0;
        int n = str.length();
        while (left < n) {
            int right = left+1;
            while(right < n && str.charAt(right) != str.charAt(right-1)){
                right++;
            }
            if(right-left>=3)
                ans = Math.max(right-left,ans);
            left = right;
        }
        System.out.println(ans);
    }
}


第三题

给你一个字符串,里面只有ASDF四个字母,且长度为4的倍数,你可以将一个子串修改为任意一个子串,在所有修改后可以使得四个字母的个数相等的子串中,求最小子串的长度。
思路:
滑动窗口,记录比len/4多余的字母的个数,如果窗口内的字母个数>=这个个数,则这个窗口满足条件,找最小满足条件的窗口
代码:
import java.util.Scanner;
/*
输入:
ADDF
输出:
1

输入:
ASAFASAFADDD
输出:
3
 */
public class Q3 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String str = sc.nextLine();
        int n = str.length();
        int cnt = n/4;
        int Acnt = 0, Scnt = 0, Dcnt = 0, Fcnt = 0;
        for (int i = 0; i < n; i++) {
            switch (str.charAt(i)) {
                case 'A':
                    Acnt++;
                    break;
                case 'S':
                    Scnt++;
                    break;
                case 'D':
                    Dcnt++;
                    break;
                default:
                    Fcnt++;
                    break;
            }
        }
        if(Acnt == Scnt && Scnt == Dcnt && Dcnt == Fcnt) {
            System.out.println(0);
            return;
        }
        // System.out.println("A:"+Acnt+"\tS:"+Scnt+"\tD:"+Dcnt+"\tF:"+Fcnt);
        Acnt = Acnt>=cnt?Acnt-cnt:0;
        Scnt = Scnt>=cnt?Scnt-cnt:0;
        Dcnt = Dcnt>=cnt?Dcnt-cnt:0;
        Fcnt = Fcnt>=cnt?Fcnt-cnt:0;
        // System.out.println("A:"+Acnt+"\tS:"+Scnt+"\tD:"+Dcnt+"\tF:"+Fcnt);
        int ans = n;
        int Acnt1 = 0, Scnt1 = 0, Dcnt1 = 0, Fcnt1 = 0;
        int left = 0,right = 0;
        while (left < n) {
            while (right < n && (Acnt1<Acnt || Scnt1<Scnt || Dcnt1<Dcnt || Fcnt1<Fcnt)) {
                char ch = str.charAt(right++);
                switch (ch) {
                    case 'A':
                        Acnt1++;
                        break;
                    case 'S':
                        Scnt1++;
                        break;
                    case 'D':
                        Dcnt1++;
                        break;
                    default:
                        Fcnt1++;
                        break;
                }
            }
            // System.out.println("left:"+left+"\tright:"+right+"\tstr:"+str.substring(left,right));
            if((Acnt1>=Acnt && Scnt1>=Scnt && Dcnt1>=Dcnt && Fcnt1>=Fcnt))
                ans = Math.min(ans,right-left);
            char ch = str.charAt(left++);
            switch (ch) {
                case 'A':
                    Acnt1--;
                    break;
                case 'S':
                    Scnt1--;
                    break;
                case 'D':
                    Dcnt1--;
                    break;
                default:
                    Fcnt1--;
                    break;
            }
        }
        System.out.println(ans);
    }
}


第四题

小明做书架,题目太长了,很难复述,欢迎大佬们补充,我看题目看了十几分钟才明白。
思路:
线段树+二分查找
先通过二分查找找出长度
然后通过线段树查找这个长度区间内的最大值和最小值,判断是否满足条件
代码:
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
/*
输入:
3 3
14 12 10
输出:
2 2
1 2
2 3

输入:
2 0
10 10
输出:
2 1
1 2

输入:
4 5
8 19 10 13
输出:
2 1
3 4
 */
public class Q4 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int bookCnt = sc.nextInt();
        int k = sc.nextInt();//高度差不能超过k
        int h[] = new int[bookCnt+1];//第i本书的高度
        NumTree tree = new NumTree(1, bookCnt);
        for (int i = 1; i <= bookCnt; i++) {
            h[i] = sc.nextInt();
            tree.update(i, h[i]);
        }
        List<Integer> idx = new ArrayList();
        int a = 1;
        int low = 1, high = bookCnt;
        while (low <= high) {
            int mid = (low+high) >> 1;
            //判断长度为mid是否能满足条件
            List<Integer> list = new ArrayList<>();
            for (int i = 1; i + mid -1 <= bookCnt; i++) {
                int res[] = tree.query(i,i+mid-1);
                if(res[1]-res[0] <= k) {
                    list.add(i);
                }
            }
            //找不到
            if(list.size()==0) {
                high = mid-1;
            }
            else {
                low = mid+1;
                a = mid;
                idx = list;
            }
        }
        System.out.println(a+" "+idx.size());
        for (int i = 0; i < idx.size(); i++) {
            System.out.println(idx.get(i)+" "+(idx.get(i)+a-1));
        }
    }
}

class NumTree{
    int left;
    int right;
    int min;
    int max;
    NumTree lchild;
    NumTree rchild;

    public NumTree(int left, int right){
        this.left = left;
        this.right = right;
        this.min = Integer.MAX_VALUE;
        this.max = Integer.MIN_VALUE;
        if(left < right) {
            int mid = (left+right)>>1;
            lchild = new NumTree(left, mid);
            rchild = new NumTree(mid+1, right);
        }
        else {
            lchild = rchild = null;
        }
    }

    public void update(int idx, int val) {
        if(idx < left || idx > right) return;
        this.max = Math.max(this.max, val);
        this.min = Math.min(this.min, val);
        if(left != right) {
            int mid = (left + right) >> 1;
            if (idx <= mid) {
                lchild.update(idx, val);
            } else {
                rchild.update(idx, val);
            }
        }
    }

    public int[] query(int L, int R) {
        if(R < left || L > right) {
            return new int[]{Integer.MAX_VALUE,Integer.MIN_VALUE};
        }
        else if(L <= left && R >= right) {
            return new int[]{min,max};
        }
        else {
            int res1[] = lchild.query(L,R);
            int res2[] = rchild.query(L,R);
            return new int[]{Math.min(res1[0],res2[0]),Math.max(res1[1],res2[1])};
        }
    }
}


#字节跳动##字节笔试##字节跳动笔试##2023一起秋招吧##23届秋招笔面经#
全部评论
第一题居然不需要用二分而是直接做剪枝就行了...... 我第四题是滑动窗口90% 我10点40才开始,能拿390已经满足了
点赞 回复 分享
发布于 2022-09-18 12:06 广东
今天题目太简单了,应该都能ak
点赞 回复 分享
发布于 2022-09-18 12:15 江苏

相关推荐

03-06 12:44
已编辑
吉林大学 Java
是个千人厂,没听过名字。1.&nbsp;做一个自我介绍。2.&nbsp;你这个项目和技术栈从哪里学的?有报辅导班嘛[答&nbsp;都是是自己网上学的,学校教的东西没用]3.&nbsp;我看了你放在github上的项目,前端也是你写的嘛[答&nbsp;AI写的,90%精力用于后端开发,前端单纯用于作为后端逻辑的可视化技术验证(骗你的其实后端也是AI写的)]4.&nbsp;好,你觉得这些技术栈研究得最深刻的是哪个[答&nbsp;八股压根没背到后面,昨晚背了MySQL就说MySQL]5.&nbsp;那讲一下MySQL的索引[答&nbsp;从B+树选型一路吟唱到联合索引,索引失效]6.&nbsp;联合索引ABC问题,AB走索引嘛,BC走索引嘛?BAC走索引嘛?A&nbsp;or&nbsp;B&nbsp;走索引嘛[走,不走,走,不走。面试官点头说可以]7.&nbsp;讲一下项目里Redission分布式锁实现8.&nbsp;Watchdog机制具体是怎么工作9.&nbsp;消息队列有考虑过Kafka嘛,怎么选型的10.&nbsp;你这个项目消息队列可能出现什么问题,怎么解决这个问题?[瞎扯没用的,被面试官引导答了视频处理可能产生消息堆积问题,然后开始吟唱]11.&nbsp;文件分片自己写的还是用的什么框架?上传进度的Redis数据结构?上传的视频有多大?小分片大小?12.&nbsp;项目里Redis会话记忆是啥意思?[面试官说不行,没人把这个全放Redis里[生气R]]13.&nbsp;那这和直接查数据库有什么区别[扯了Token成本和解决幻觉问题之类的,给面试官听笑了,我最后也没绷住]14.&nbsp;你平时是怎么使用AI&nbsp;coding的15.&nbsp;算法,给了我一个leedcode链接,一看做过了。然后换了一道三数之和,也做过了。然后面试官说算了,让我讲讲思路吧反问:1.有什么需要提高的地方2.介绍一下部门业务有哪些这个面试官真的感官非常非常好,问问题还疯狂引导,感觉不会也会了。找实习&nbsp;&nbsp;牛客AI配图神器#
查看15道真题和解析
点赞 评论 收藏
分享
评论
7
19
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务