leetcode778

题目的提示grid[i][j] 位于区间 [0, ..., N*N - 1] 内。所以想到的是遍历 0 到N*N-1  如果满足就返回

 先定义一个满足优先队列的bean

  static class Tmo implements Comparable<Tmo> {
        public int x;

        public int y;

        public int value;

        public Tmo(int x, int y, int value) {
            this.x = x;
            this.y = y;
            this.value = value;
        }


        @Override
        public int compareTo(Tmo o) {
            return this.value -o.value;
        }
    }

 

这样的话代码如下

 1  public static int swimInWater(int[][] grid) {
 2 
 3         int[][] forward = new int[][]{{0,1},{1,0},{0,-1},{-1,0}};
 4 
 5 
 6         int n = grid.length;
 7         int len = n*n-1;
 8         for (int i = 0; i <= len; i++) {
 9             //如果有满足K的就返回
10             int k = i;
11             PriorityQueue<Tmo> pq = new PriorityQueue<>();
12             pq.offer(new Tmo(0,0,grid[0][0]));
13 
14             int[][] exist = new int[n][n];
15             exist[0][0] = 1;
16 
17             while (!pq.isEmpty()){
18                 Tmo poll = pq.poll();
19                 int x = poll.x;
20                 int y = poll.y;
21                 //朝着四个方向出发  选择短路径 如果结果是N,N则返回
22                 for (int j = 0; j < forward.length && poll.value <= k; j++) {
23                     //控制方向
24                     int[] forw = forward[j];
25                     int tx = x+forw[0];
26                     int ty = y+forw[1];
27                     if (tx <0 || tx >= n || ty <0 || ty >= n || exist[tx][ty] == 1 || grid[tx][ty] > k  ){
28                         continue;
29                     }
30                     if (tx == n-1 && ty ==  n-1 ){
31                         return k;
32                     }
33                     exist[tx][ty] = 1;
34                     pq.offer(new Tmo(tx,ty,grid[tx][ty]));
35 
36                 }
37 
38             }
39 
40 
41 
42         }
43 
44 
45 
46         return -1;
47     }
48 
49 

 

这样算下来需要遍历从0开始一直遍历到符合的。然后可以改为二分查找法来找到那个合适的

 

 1     public static int swimInWater(int[][] grid) {
 2 
 3         int[][] forward = new int[][]{{0,1},{1,0},{0,-1},{-1,0}};
 4 
 5 
 6         int n = grid.length;
 7         int start = 0;
 8         int end = n*n-1;
 9         while (start <= end){
10             //如果有满足K的就返回
11             int middle = (end + start)/2;
12 
13             PriorityQueue<Tmo> pq = new PriorityQueue<>();
14             pq.offer(new Tmo(0,0,grid[0][0]));
15 
16             int[][] exist = new int[n][n];
17             exist[0][0] = 1;
18             boolean search = false;
19             while (!pq.isEmpty()){
20                 Tmo poll = pq.poll();
21                 int x = poll.x;
22                 int y = poll.y;
23                 //朝着四个方向出发  选择短路径 如果结果是N,N则返回
24                 for (int j = 0; j < forward.length && poll.value <= middle; j++) {
25                     //控制方向
26                     int[] forw = forward[j];
27                     int tx = x+forw[0];
28                     int ty = y+forw[1];
29                     if (tx <0 || tx >= n || ty <0 || ty >= n || exist[tx][ty] == 1 || grid[tx][ty] > middle  ){
30                         continue;
31                     }
32                     if (tx == n-1 && ty ==  n-1 ){
33                         search = true;
34                         break;
35                     }
36                     exist[tx][ty] = 1;
37                     pq.offer(new Tmo(tx,ty,grid[tx][ty]));
38 
39                 }
40 
41             }
42             if (search){
43                 //当前点符合 就寻找小的是不是有符合的
44                 end = middle-1;
45             }else {
46                 start = middle +1;
47             }
48         }
49 
50 
51 
52         return start;
53     }
54 
55 

 

不过上面两种方式遍历time进行BFS,如果值没有限制的话就没法这样做。所以可以换个思路就是从0,0开始每次找到周围最小的然后继续查找,这样保证到最后找到结果时路径里的最大值是最小的。

 public static int swimInWater2(int[][] grid) {

        int[][] forward = new int[][]{{0,1},{1,0},{0,-1},{-1,0}};


        int n = grid.length;


        PriorityQueue<Tmo> pq = new PriorityQueue<>();
        pq.offer(new Tmo(0,0,grid[0][0]));

        int max = 0;
        int[][] exist = new int[n][n];
        exist[0][0] = 1;
        while (!pq.isEmpty()){

            Tmo poll = pq.poll();
            int x = poll.x;
            int y = poll.y;
            int t = poll.value;
            max = Math.max(max,t);
            if (x == n-1 && y ==  n-1 ){
                return max;
            }

            //朝着四个方向出发  选择短路径 如果结果是N,N则返回
            for (int j = 0; j < forward.length ; j++) {
                //控制方向
                int[] forw = forward[j];
                int tx = x+forw[0];
                int ty = y+forw[1];
                if (tx <0 || tx >= n || ty <0 || ty >= n || exist[tx][ty] == 1   ){
                    continue;
                }

                exist[tx][ty] = 1;
                pq.offer(new Tmo(tx,ty,grid[tx][ty]));

            }

        }
        return -1;
    }

可以看到三种方式的提升还是比较明显

 

posted @ 2021-01-19 13:01  雨落寒沙  阅读(96)  评论(0编辑  收藏  举报