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給的題目中,代碼很多,所以我這裏也寫得比較多。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章