问题:
给定坐标系:(0,0)~(10^6,10^6)
起点坐标:source(x,y)
目标坐标:target(x,y)
障碍物坐标list:block
求是否能从起点坐标,到目标坐标。
(遇到障碍物,无法继续前进)
Example 1: Input: blocked = [[0,1],[1,0]], source = [0,0], target = [0,2] Output: false Explanation: The target square is inaccessible starting from the source square because we cannot move. We cannot move north or east because those squares are blocked. We cannot move south or west because we cannot go outside of the grid. Example 2: Input: blocked = [], source = [0,0], target = [999999,999999] Output: true Explanation: Because there are no blocked cells, it is possible to reach the target square. Example 3: Input: blocked = [[10,9],[9,10],[10,11],[11,10]], source = [0,0], target = [10,10] Output: false Example 4: Input: blocked = [[0,199],[1,198],[2,197],[3,196],[4,195],[5,194],[6,193],[7,192],[8,191],[9,190],[10,189],[11,188],[12,187],[13,186],[14,185],[15,184],[16,183],[17,182],[18,181],[19,180],[20,179],[21,178],[22,177],[23,176],[24,175],[25,174],[26,173],[27,172],[28,171],[29,170],[30,169],[31,168],[32,167],[33,166],[34,165],[35,164],[36,163],[37,162],[38,161],[39,160],[40,159],[41,158],[42,157],[43,156],[44,155],[45,154],[46,153],[47,152],[48,151],[49,150],[50,149],[51,148],[52,147],[53,146],[54,145],[55,144],[56,143],[57,142],[58,141],[59,140],[60,139],[61,138],[62,137],[63,136],[64,135],[65,134],[66,133],[67,132],[68,131],[69,130],[70,129],[71,128],[72,127],[73,126],[74,125],[75,124],[76,123],[77,122],[78,121],[79,120],[80,119],[81,118],[82,117],[83,116],[84,115],[85,114],[86,113],[87,112],[88,111],[89,110],[90,109],[91,108],[92,107],[93,106],[94,105],[95,104],[96,103],[97,102],[98,101],[99,100],[100,99],[101,98],[102,97],[103,96],[104,95],[105,94],[106,93],[107,92],[108,91],[109,90],[110,89],[111,88],[112,87],[113,86],[114,85],[115,84],[116,83],[117,82],[118,81],[119,80],[120,79],[121,78],[122,77],[123,76],[124,75],[125,74],[126,73],[127,72],[128,71],[129,70],[130,69],[131,68],[132,67],[133,66],[134,65],[135,64],[136,63],[137,62],[138,61],[139,60],[140,59],[141,58],[142,57],[143,56],[144,55],[145,54],[146,53],[147,52],[148,51],[149,50],[150,49],[151,48],[152,47],[153,46],[154,45],[155,44],[156,43],[157,42],[158,41],[159,40],[160,39],[161,38],[162,37],[163,36],[164,35],[165,34],[166,33],[167,32],[168,31],[169,30],[170,29],[171,28],[172,27],[173,26],[174,25],[175,24],[176,23],[177,22],[178,21],[179,20],[180,19],[181,18],[182,17],[183,16],[184,15],[185,14],[186,13],[187,12],[188,11],[189,10],[190,9],[191,8],[192,7],[193,6],[194,5],[195,4],[196,3],[197,2],[198,1],[199,0]] , source = [0,0] , target = [200,200] Output: false Example 5: Input: blocked = [[691938,300406],[710196,624190],[858790,609485],[268029,225806],[200010,188664],[132599,612099],[329444,633495],[196657,757958],[628509,883388]] , source = [655988,180910] , target = [267728,840949] Output: true Constraints: 0 <= blocked.length <= 200 blocked[i].length == 2 0 <= xi, yi < 106 source.length == target.length == 2 0 <= sx, sy, tx, ty < 106 source != target It is guaranteed that source and target are not blocked.
解法:BFS
⚠️ 注意:
本题到重点为:
坐标系范围太大,会容易超时。
那么,我们考虑,block的范围,最大阻断起点和终点的方法:
两点之间,使用block形成对角线,一端接触x轴,另一端接触y轴。
那么两点若尝试超过,这个对角线和坐标系边缘构成的最大面积,那么一定可以相连。
0th _________________________ The sum of the area available equals 1+2+3+4+5+...+198+199=(1+199)*199/2=19900 (trapezoid sum) |-------------------- X |-------------------X | . | . . . . X . X 200 | X
block.size=cnt(例如最大200)
那么上图block节点X和坐标系,构成的三角形面积 maxstep 为:
- (cnt-1)*cnt/2
解释:(1+cnt-1)*(cnt-1)/2 (首项+末项)*项数/2
由于两点情况一样,
因此要分别对source和target进行尝试,向外扩展最大面积maxstep后,仍然有路径,那么返回true。
代码参考:
1 class pii{ 2 public: 3 int a; 4 int b; 5 pii(int a1, int b1){ 6 a = a1; 7 b = b1; 8 } 9 string to_string() { 10 return string(::to_string(a)+"_"+::to_string(b)); 11 } 12 }; 13 class Solution { 14 public: 15 int dir[5]={1,0,-1,0,1}; 16 int maxstep = 0; 17 unordered_set<string> blockset; 18 bool bfs(vector<int>& source, vector<int>& target) { 19 queue<pii> q; 20 unordered_set<string> visited; 21 q.push(pii(source[0], source[1])); 22 visited.insert(pii(source[0], source[1]).to_string()); 23 while(!q.empty()) { 24 int sz = q.size(); 25 for(int i=0; i<sz; i++) { 26 pii cur = q.front(); 27 q.pop(); 28 if(cur.a==target[0] && cur.b==target[1] 29 || visited.size() > maxstep) 30 return true; 31 for(int j=1; j<5; j++) { 32 int x = cur.a+dir[j-1]; 33 int y = cur.b+dir[j]; 34 if(x<0 || y<0 || x>=1000000 || y>=1000000 35 || blockset.count(pii(x,y).to_string())) continue; 36 if(visited.insert(pii(x,y).to_string()).second) { 37 q.push(pii(x,y)); 38 } 39 } 40 } 41 } 42 return false; 43 } 44 bool isEscapePossible(vector<vector<int>>& blocked, vector<int>& source, vector<int>& target) { 45 int cnt = 0; 46 for(auto b:blocked) { 47 blockset.insert(pii(b[0],b[1]).to_string()); 48 cnt++; 49 } 50 maxstep = (cnt-1)*cnt/2; 51 52 return bfs(source, target) && bfs(target, source); 53 } 54 };