标签:Leetcode70 int res 双周 queue 2146 grid && new
题目描述
解题思路
核心办法是:BFS+优先队列
第一个思想,就是从起点开始,向四周进行BFS。需要注意的是记录是否访问viewed的数组。
第二个思想,排序,按照BFS的方式遍历之后,先遍历到的层级的点,一定是距离最小的。
那么,就要考虑相同层级的点之间如何排序。这个排序的规则已经由题目规定,按照价格、坐标来排序。排序的关键就是写好优先队列的排序方法。
解题代码
方法一
import java.util.*;
public class Solution5973 {
public static void main(String[] args) {
int[][] grid = {{1, 2, 0, 1}, {1, 3, 3, 1}, {0, 2, 5, 1}};
int[] pricing = {2, 3};
int[] start = {2, 3};
int k = 2;
List<List<Integer>> res = new Solution5973().highestRankedKItems(grid, pricing, start, k);
System.out.println(res);
}
public List<List<Integer>> highestRankedKItems(int[][] grid, int[] pricing, int[] start, int k) {
Comparator<int[]> c = new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
int o1x = o1[0];
int o1y = o1[1];
int o2x = o2[0];
int o2y = o2[1];
if (grid[o1x][o1y] < grid[o2x][o2y]) {
return -1;
} else if (grid[o1x][o1y] > grid[o2x][o2y]) {
return 1;
} else {
if (o1x < o2x) {
return -1;
} else if (o1x > o2x) {
return 1;
} else {
return o1y - o2y;
}
}
}
};
List<List<Integer>> res = new ArrayList<>();
int grid_x = grid.length;
int grid_y = grid[0].length;
int low = pricing[0];
int high = pricing[1];
// 定义BFS的观察路径
boolean[][] viewed = new boolean[grid_x][grid_y];
// 定义queue
LinkedList<int[]> queue = new LinkedList<>();
queue.add(start);
while (!queue.isEmpty()) {
int size = queue.size();
PriorityQueue<int[]> priorityQueue = new PriorityQueue<>(c);
for (int i = 0; i < size; i++) {
int[] s = queue.poll();
int x = s[0];
int y = s[1];
//处理当前点
if (x >= 0 && x <= grid_x && y >= 0 && y <= grid_y &&
!viewed[x][y] && grid[x][y] != 0) {
queue.offer(new int[]{x, y});
viewed[x][y] = true;
if (grid[x][y] >= low && grid[x][y] <= high) {
priorityQueue.add(new int[]{x, y});
}
// 扩展当前点的周围4个点
if (x - 1 >= 0 && !viewed[x - 1][y] && grid[x - 1][y] != 0) {
queue.offer(new int[]{x - 1, y});
}
if (x + 1 < grid_x && !viewed[x + 1][y] && grid[x + 1][y] != 0) {
queue.offer(new int[]{x + 1, y});
}
if (y - 1 >= 0 && !viewed[x][y - 1] && grid[x][y - 1] != 0) {
queue.offer(new int[]{x, y - 1});
}
if (y + 1 < grid_y && !viewed[x][y + 1] && grid[x][y + 1] != 0) {
queue.offer(new int[]{x, y + 1});
}
}
}
//从优先队列中取数字
while (!priorityQueue.isEmpty()) {
int[] r = priorityQueue.poll();
ArrayList<Integer> arrayList = new ArrayList<>();
arrayList.add(r[0]);
arrayList.add(r[1]);
res.add(arrayList);
if (res.size() == k) {
return res;
}
}
}
return res;
}
}
方法二
public class Solution5973_2 {
public static void main(String[] args) {
int[][] grid = {{1, 2, 0, 1}, {1, 3, 3, 1}, {0, 2, 5, 1}};
int[] pricing = {2, 3};
int[] start = {2, 3};
int k = 2;
List<List<Integer>> res = new Solution5973_2().highestRankedKItems(grid, pricing, start, k);
System.out.println(res);
}
public List<List<Integer>> highestRankedKItems(int[][] grid, int[] pricing, int[] start, int k) {
Comparator<int[]> c = new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
int o1x = o1[0];
int o1y = o1[1];
int o2x = o2[0];
int o2y = o2[1];
if (grid[o1x][o1y] < grid[o2x][o2y]) {
return -1;
} else if (grid[o1x][o1y] > grid[o2x][o2y]) {
return 1;
} else {
if (o1x < o2x) {
return -1;
} else if (o1x > o2x) {
return 1;
} else {
return o1y - o2y;
}
}
}
};
List<List<Integer>> res = new ArrayList<>();
int grid_x = grid.length;
int grid_y = grid[0].length;
LinkedList<int[]> queue = new LinkedList<>();
boolean[][] viewed = new boolean[grid_x][grid_y];
viewed[start[0]][start[1]] = true;
if (grid[start[0]][start[1]] != 0) {
queue.add(start);
}
if (grid[start[0]][start[1]] <= pricing[1] && grid[start[0]][start[1]] >= pricing[0]) {
ArrayList<Integer> arrayList = new ArrayList<>();
arrayList.add(start[0]);
arrayList.add(start[1]);
res.add(arrayList);
if (res.size() == k) {
return res;
}
}
int low = pricing[0];
int high = pricing[1];
while (!queue.isEmpty()) {
int size = queue.size();
PriorityQueue<int[]> priorityQueue = new PriorityQueue<>(c);
for (int i = 0; i < size; i++) {
int[] s = queue.poll();
int x = s[0];
int y = s[1];
// 扩展4个点
if (x - 1 >= 0 && !viewed[x - 1][y] && grid[x - 1][y] != 0) {
queue.offer(new int[]{x - 1, y});
viewed[x - 1][y] = true;
if (grid[x - 1][y] >= low && grid[x - 1][y] <= high) {
priorityQueue.add(new int[]{x - 1, y});
}
}
if (x + 1 < grid_x && !viewed[x + 1][y] && grid[x + 1][y] != 0) {
queue.offer(new int[]{x + 1, y});
viewed[x + 1][y] = true;
if (grid[x + 1][y] >= low && grid[x + 1][y] <= high) {
priorityQueue.add(new int[]{x + 1, y});
}
}
if (y - 1 >= 0 && !viewed[x][y - 1] && grid[x][y - 1] != 0) {
queue.offer(new int[]{x, y - 1});
viewed[x][y - 1] = true;
if (grid[x][y - 1] >= low && grid[x][y - 1] <= high) {
priorityQueue.add(new int[]{x, y - 1});
}
}
if (y + 1 < grid_y && !viewed[x][y + 1] && grid[x][y + 1] != 0) {
queue.offer(new int[]{x, y + 1});
viewed[x][y + 1] = true;
if (grid[x][y + 1] >= low && grid[x][y + 1] <= high) {
priorityQueue.add(new int[]{x, y + 1});
}
}
}
//从优先队列中取数字
while (!priorityQueue.isEmpty()) {
int[] r = priorityQueue.poll();
ArrayList<Integer> arrayList = new ArrayList<>();
arrayList.add(r[0]);
arrayList.add(r[1]);
res.add(arrayList);
if (res.size() == k) {
return res;
}
}
}
return res;
}
}
两个方法的区别就是在判断点的时机
方法一是在点的出队的时候,方法二是在点入队之前。
解题结果
标签:Leetcode70,int,res,双周,queue,2146,grid,&&,new 来源: https://blog.csdn.net/Kangyucheng/article/details/122690542
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。