【leetcode】Weekly Contest 92

  emm,两天打的周赛,万年三题qaq,不过这次题目好像比上次的难一丢丢。

1.Transpose Matrix

  把矩阵A[i][j]的每个元素改成B[j][i],超级超级大水题,然后wa了两发qaq。

 1     public int[][] transpose(int[][] A) {
 2         int row = A.length;
 3         int clon = A[0].length;
 4         int[][] res = new int[clon][row];
 5         for(int i = 0;i<row;i++){
 6             for(int j = 0; j<clon;j++){
 7                 res[j][i] = A[i][j];
 8             }
 9         }
10         return res;
11     }

2. Smallest Subtree with all the Deepest Nodes

  一开始脑子抽了,没理解到底求的是什么,看了两三遍才反应过来求含最深节点的根节点(emm,这个题意有点难解释,看例子比较好)。

  然后发现其实求每个节点的深度,如果其左孩子节点和右孩子节点最大深度是一样的就返回该节点(所求的根节点),如果不是,就进入深度大的那个节点继续判断即可。

  我的代码就是先求每个节点的深度,然后再去找所求节点,怕递归太深超时就用hashmap记录了每个节点的深度,这样就不需要重复计算。

 1     HashMap<TreeNode, Integer> map;
 2     public TreeNode subtreeWithAllDeepest(TreeNode root) {
 3         if(root == null){
 4             return null;
 5         }
 6         map = new HashMap<>();
 7         while(getDeepth(root.left) != getDeepth(root.right)){
 8             if(getDeepth(root.right) > getDeepth(root.left)){
 9                 root = root.right;
10             }else {
11                 root = root.left;
12             }
13         }
14         return root;
15     }
16     public int getDeepth(TreeNode root){
17         if(root == null){
18             return 0;
19         }else if(map.containsKey(root)){
20             return map.get(root);
21         }else {
22             int deepth = Math.max(getDeepth(root.left), getDeepth(root.right))+1;
23             map.put(root, deepth);
24             return deepth;
25         }
26     }

 

3. Prime Palindrome

  第三题题意很简单,就是给一个数字,求不小于该数字的最小回文素数,emm,第一反应就是暴力肯定不行,然后就陷入了沉思中。

  那么肯定要先找出一种遍历回文数或素数的办法,因为素数遍历不用暴力法我不会qaq,找依次遍历回文数好像简单很多,note提示了答案肯定小于2*10^8,那么我们只需要最大遍历到四位数,再把后半部分补全即可,这样只需要遍历最大1w次,再判断每个是否是素数即可。

  不过奇数位和偶数位判断好像很麻烦的样子,又想到了偶数位回文数肯定不可能是素数(除了11),因为会被11整除啦,比如abba,可以拆成1111*a+110*(b-a)。那么生成回文数的方法只需要写一个就好啦!

 1     boolean isPrime(int n){//判断是否是素数
 2         if(n == 1){
 3             return false;
 4         }
 5         if(n == 2){
 6             return true;
 7         }
 8         int k = (int) Math.sqrt(n);
 9         for(int i = 2;i<=k;i++){
10             if(n%i==0){
11                 return false;
12             }
13         }
14         return true;
15     }
16     
17     int getPalindrome(int n){//生成奇数位回文数
18         int res=n/10;
19         while(n!=0)
20         {
21             res=res*10+n%10;//从低到高依次把该位数字添加到末尾
22             n/=10;
23         }
24         return res;
25     }
26     
27     public int primePalindrome(int N) {
28         if(N<=11){//小于11直接遍历即可
29             for(int i = N;i<=11;i++){
30                 if(isPrime(i)){
31                     return i;
32                 }
33             }
34         }
35         for(int i = 10;;i++){//比11大就遍历回文数
36             int palindrome = getPalindrome(i);
37             if(palindrome<N){
38                 continue;
39             }
40             if(isPrime(palindrome)){
41                 return palindrome;
42             }
43         }
44     }

4.Shortest Path to Get All Keys

 

   其实,补完题发现不是很难qaq,没做出来一个原因是明明想着用bfs搜就好了,但是写的时候被一股神秘力量操控,一直在想用递归写bfs,等反应过来的时候时间不太够了,这种限时训练还是需要提高思维和编码能力。

  bfs搜的时候把key也记录下来就好啦,不难不难(逃。

 1 class Path {
 2         int bitMask;//记录key的数量,111(7)表示有三把钥匙,abc
 3         int x;
 4         int y;
 5 
 6         public Path(int x, int y, int bitMask) {
 7             this.x = x;
 8             this.y = y;
 9             this.bitMask = bitMask;
10         }
11 
12         @Override
13         public boolean equals(Object o) {
14             Path p = (Path) o;
15             return bitMask == p.bitMask && x == p.x && y == p.y;
16         }
17 
18         @Override
19         public int hashCode() {//用set的时候改写一下hashcode和equals
20             return 1331 * bitMask + 31 * x + 101 * y;
21         }
22     }
23 
24     private static final int[][] directions = new int[][]{{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
25 
26     public int shortestPathAllKeys(String[] grid) {
27         char[][] board = new char[grid.length][grid[0].length()];
28         int[] num = new int[1];
29         Path start = new Path(0, 0, 0);
30         initialize(grid, start, num, board);
31 
32         Queue<Path> queue = new LinkedList<>();
33         Set<Path> visited = new HashSet<>();
34 
35         queue.offer(start);
36         visited.add(start);
37         int step = 0;
38 
39         while(!queue.isEmpty()) {
40             int size = queue.size();
41 
42             for(int i = 0; i < size; i++) {
43                 Path current = queue.poll();
44 
45                 if(current.bitMask == (1 << num[0]) - 1) {
46                     return step;
47                 }
48 
49                 for(int[] direction : directions) {
50                     int x = direction[0] + current.x;
51                     int y = direction[1] + current.y;
52                     int bitMask = current.bitMask;
53 
54                     if(x >= 0 && x < grid.length && y >= 0 && y < grid[0].length()) {
55                         char ch = board[x][y];
56 
57                         if(ch == '#') {
58                             continue ;
59                         }
60                         else if(ch >= 'a' && ch <= 'f') {
61                             bitMask |= 1 << (ch - 'a');
62                         }
63                         else if(ch >= 'A' && ch <= 'F' && ((bitMask >> (ch - 'A')) & 1) == 0) {
64                             continue ;
65                         }
66 
67                         if(visited.add(new Path(x, y, bitMask))) {
68                             queue.offer(new Path(x, y, bitMask));
69                         }
70                     }
71                 }
72             }
73             step++;
74         }
75         return -1;
76 
77     }
78 
79     private void initialize(String[] grid, Path start, int[] num, char[][] board) {//找到起点和key有多少个
80         for(int i = 0; i < grid.length; i++) {
81             for(int j = 0; j < grid[0].length(); j++) {
82                 char ch = grid[i].charAt(j);
83                 board[i][j] = ch;
84 
85                 if(ch == '@') {
86                     start.x = i;
87                     start.y = j;
88                 }
89 
90                 if(ch >= 'a' && ch <= 'f') {
91                     num[0]++;
92                 }
93             }
94         }
95     }

  代码很长,主要就是bfs以及用一个int记录key是否已经拿到了,注释也写啦,题目也说了key一定是前k个小写字母。

posted @ 2018-07-10 19:43  zhangdapao  阅读(280)  评论(0编辑  收藏  举报