【leetcode】Weekly Contest 93

  又是周末,leetcode周赛,菜鸡下定决心要AK一次,然后失败了,周常三题QAQ。

1.Binary Gap

  第一题给一个数字,让你找数字的二进制中相邻的1最大距离是多少,直接扫描一遍就好啦。

 1     public int binaryGap(int N) {
 2         int last = -1;
 3         int res = 0;
 4         for(int i = 0;N>0;N/=2,i++){
 5             if(N%2 == 1){
 6                 if(last!=-1){
 7                     res = Math.max(res, i-last);
 8                 }
 9                 last = i;
10             }
11         }
12         return res;
13     }

2.Binary Gap

  第二题也不难,找到与所给的数字位数相同的2^n次方数,然后比较所给的数字构成是不是一样,把每一位拆开来扔进一个10位的int数组里比较就行。因为给的数字最大是10^9,因此直接暴力求即可。

 1     public boolean reorderedPowerOf2(int N) {
 2         for(int i = 0;;i++){
 3             int a = (int)Math.pow(2, i);
 4             int com = compareLength(N, a);
 5             if(com!=1){
 6                 if(com == 0){//找到位数相同的(后来发现好像不加这个条件也可以,反正范围小)
 7                     if(compare(N, a)){
 8                         return true;
 9                     }
10                 }
11             }else {
12                 return false;
13             }
14         }
15     }
16     
17     boolean compare(int N,int a){//比较构成是否相同
18         int[] num = new int[10];
19         while(N!=0){
20             num[N%10]++;
21             N/=10;
22         }
23         while(a!=0){
24             num[a%10]--;
25             a/=10;
26         }
27         for(int i = 0;i<10;i++){
28             if(num[i] != 0){
29                 return false;
30             }
31         }
32         return true;
33     }
34     
35     int compareLength(int N,int a){//比较两个数位数是否相同
36         while(a!=0&&N!=0){
37             N/=10;
38             a/=10;
39         }
40         if(a!=0){
41             return 1;
42         }else if (N!=0) {
43             return -1;
44         }
45         return 0;
46     }

3.Advantage Shuffle

  第三题用贪心做就好了,先把A数组排序,对B数组中的每个数B[i],从A数组中找一个最小的并且大于B[i]的数(未被使用过的),如果找不到,就放一个最小的且没被使用过的(有点像田忌赛马的感觉),举个例子A【1,5】,B【2,3】,对于这种数组,5放在第一位和第二位都是一样的,因此无需考虑某个位置放的数是否会对后面放置数字产生影响。

 1     public int[] advantageCount(int[] A, int[] B) {
 2         Arrays.sort(A);
 3          int temp;
 4         for(int i = 0,j=A.length-1;i<j;i++,j--){//sort从小到大,翻转一下QAQ
 5             temp = A[i];
 6             A[i] = A[j];
 7             A[j] = temp;
 8         }
 9         int[] C = new int[A.length];
10         Arrays.fill(C, -1);
11         boolean[] use = new boolean[A.length];
12         for(int i = 0;i<A.length;i++){
13             for(int j = A.length-1;j>=0;j--){
14                 if(!use[j] && A[j]>B[i]){
15                     C[i] = A[j];
16                     use[j] = true;
17                     break;
18                 }
19             }
20             if(C[i] == -1){
21                 for(int j = A.length-1;j>=0;j--){
22                     if(!use[j]){
23                         C[i] = A[j];
24                         use[j] = true;
25                         break;
26                     }
27                 }
28             }
29         }
30         return C;
31     }

 

4.Minimum Number of Refueling Stops

  题目不难理解,一开始用贪心做了,后来发现贪心会出现问题,可能前面的加油站加油是能到达目标点的,但是贪心只考虑当前能到最远的位置,就可能会出现一些傻傻的答案。然后看了一下时间不多啦,就没怎么思考尝试dfs求解了,虽然感觉会超时,不过最终真的超时啦!

  后来补题的时候呢,发现别人写的好简洁QAQ,自己学着码了一个。

 1     public int minRefuelStops(int target, int startFuel, int[][] stations) {
 2         Queue<Integer> queue = new PriorityQueue<>();
 3         int d = startFuel;
 4         int last = 0;
 5         int res = 0;
 6         while(true){
 7             for(;last<stations.length&&d>=stations[last][0];last++){//从前往后找到加了res次油后能到达的位置
 8                 queue.offer(-stations[last][1]);//优先队列默认小根堆,加个负号就能少写一个比较器,这他喵的也太聪明了吧
 9             }
10             if(d>=target){
11                 return res;
12             }
13             if(queue.isEmpty()){
14                 return -1;
15             }
16             d += -queue.poll();
17             res++;
18         }
19     }
posted @ 2018-07-15 11:56  zhangdapao  阅读(275)  评论(0编辑  收藏  举报