2021 vivo校招提前批笔试解析

题目不能完整的记下来,目测后面vivo会把题目放到牛客上,这里先给一些解析

1、种花问题

刚发现原来是Leetcode上的605题

假设你有一个很长的花坛,一部分地块种植了花,另一部分却没有。可是,花卉不能种植在相邻的地块上,它们会争夺水源,两者都会死去。

给定一个花坛(表示为一个数组包含0和1,其中0表示没种植花,1表示种植了花),和一个数 n 。能否在不打破种植规则的情况下种入 n 朵花?能则返回True,不能则返回False。

示例 1:

输入: flowerbed = [1,0,0,0,1], n = 1
输出: True
示例 2:

输入: flowerbed = [1,0,0,0,1], n = 2
输出: False
注意:

数组内已种好的花不会违反种植规则。
输入的数组长度范围为 [1, 20000]。
n 是非负整数,且不会超过输入数组的大小。

刚开始我以为是动态规划问题,浪费了很多时间,后来发现是一个找规律的问题。

解题思路:

情况1:排除端点

排除端点外,我们假设可以种花的区域被花包围,也就是中间连续的0被1包围。
像下面这种情况,显然是不能种花的

1 0 0 1;

而这种情况:

1 0 0 0 1 可种1朵花
1 0 0 0 0 1 可种1朵花
1 0 0 0 0 0 1 可种2朵花
1 0 0 0 0 0 0 1 可种2朵花
1 0 0 0 0 0 0 0 1 可种3朵花
1 0 0 0 0 0 0 0 0 1 可种3朵花

不难发现,每隔着2个0,就会有多种一朵花的机会。

公式就很好推算了,中间有n个0时,可以种(n-1)/2朵花

情况2:考虑端点

当某个端点为0时,我们可以多种一朵花
1 0 0 可种1朵花
1 0 0 0 可种1朵花
1 0 0 0 0 可种2朵花
1 0 0 0 0 0 可种2朵花
1 0 0 0 0 0 0 可种3朵花
1 0 0 0 0 0 0 0 可种3朵花

情况3:花园大小只有1

当花园大小为1时,我们不能得到一个区间,我们只有一个点,对这个情况要特殊处理

综上所述,我们可以得到以下代码

    public static void main(String[] args) {
    
    
        Scanner in=new Scanner(System.in);
        int len=in.nextInt();
        int plant[]=new int[len];
        int curr=0;
        while (curr<len){
    
    
            plant[curr++]=in.nextInt();
        }
        slove(plant);
    }

    private static void slove(int nums[]){
    
    
        if(nums.length==1){
    
    
            int x=nums[0]==0?1:0;
            System.out.println(x);
            return;
        }
        int slow=0;//0
        int quick=0;//1
        int count=0;
        while (slow<nums.length&&quick<nums.length){
    
    
            while (slow<nums.length&&nums[slow]==1){
    
    
                slow++;
            }
            quick=slow;
            while (quick<nums.length&&nums[quick]==0){
    
    
                quick++;
            }
            if(quick-slow>=3){
    
    
                count+=counter(quick-slow);
            }
            //考虑端节点
            if((slow==0||quick==nums.length)&&(quick-slow>=2)){
    
    
                count++;
            }
            slow=quick;
        }
        System.out.println(count);

    }
    //计算两个空白字符之间的
    private static int counter(int sub){
    
    
        return (sub-1)/2;
    }

2、质量测试

题目大意是摔手机,跌落测试来测试手机质量。

这个题就不多说了,一道经典的Leetcode题:Leetcode-887

3、合并流水线

题目大意:
输入:n表示有几条流水线
输出:按照升序排列的,合并后的流水线

很简单,是一个排序问题。不过本题目中要求使用链表。而且源码中还留着一个静态函数,用于合并新输入的链表。

解题思路:使用小顶堆对输入的几条流水线合并,然后弹出,合并到一个流水线中。然后在那个合并函数那里,对两个链表重新合并,按照从小到达插入

public class Main {
    
    
    private static ListNode dummyNode=new ListNode(-1);
    private static ListNode currNode=dummyNode;
    public static void main(String[] args) {
    
    
        currNode=dummyNode;
        List<String> lines = new ArrayList<>();
        Scanner scanner = null;
        try {
    
    
            scanner = new Scanner(System.in);
            int totalLine=Integer.valueOf(scanner.nextLine());
            while (totalLine>0) {
    
    
                lines.add(scanner.nextLine());
                totalLine--;
                // write your code here

            }
            PriorityQueue<Integer> queue=new PriorityQueue<>();
            for (int i=0;i<lines.size();i++){
    
    
                String[] nums=lines.get(i).split(" ");
                for(String num:nums){
    
    
                    queue.offer(Integer.valueOf(num));
                }

            }

            while (queue.isEmpty()==false){
    
    
                currNode.next=new ListNode(queue.poll());
                currNode=currNode.next;
            }

        } finally {
    
    
            if (scanner != null) {
    
    
                scanner.close();
            }
        }

        // TODO output
        ListNode curr=dummyNode.next;
        while (curr!=null){
    
    
            if(curr.next==null){
    
    
                System.out.print(curr.val);
            }else {
    
    
                System.out.print(curr.val+" ");
            }

            curr=curr.next;
        }

    }

    static class ListNode {
    
    
        int val;

        ListNode next;

        ListNode(int x) {
    
    
            val = x;
        }
    }


    private static ListNode mergeNodes(ListNode head ) {
    
    
        dummyNode=merge(dummyNode.next,head);
        return dummyNode.next;

    }

    private static ListNode merge(ListNode n1,ListNode n2){
    
    
        if(n1==null||n2==null){
    
    
            return n1==null?n2:n1;
        }
        ListNode newDummy=new ListNode(-1);
        ListNode curr=newDummy;
        while(n1!=null&&n2!=null){
    
    
            int val=n1.val;
            if(n1.val>n2.val){
    
    
                val=n2.val;
                n2=n2.next;
            }else {
    
    
                n1=n1.next;
            }
            curr.next=new ListNode(val);
            curr=curr.next;
        }
        curr.next=n1==null?n2:n1;
        return newDummy.next;
    }
}

vivo给的题目中,代码很多,所以我这里也写得比较多。

猜你喜欢

转载自blog.csdn.net/qq_23594799/article/details/106603954