2.19 區間重合判斷
阿新 • • 發佈:2020-11-24
2.19 區間重合判斷
基本問題:給定一個區間[x,y]和N個無序的目標區間\([x_1,y_1],[x_2,y_2],...,[x_n,y_n]\),判斷源區間[x,y]是不是在目標區間內?
解法:
- 解法1 : 投影法 , 時間複雜度\(O(n^2)\)
- 解法2 : 區間合併法
拓展問題:如何處理二維空間中的覆蓋問題?例如在Windows桌面上有若干視窗,如何判斷某一視窗是否完全被其他視窗覆蓋?
answer:就檢查一次長的區間是否被包含&&寬的長度區間是否被包含
all coding
// 2.19 區間重合判斷 import java.util.*; class Test{ public static void main(String[] args) { /** 基本問題:給定一個區間[x,y]和N個無序的目標區間$[x_1,y_1],[x_2,y_2],...,[x_n,y_n]$,判斷源區間[x,y]是不是在目標區間內? [1,6] --> {[2,3][1,2][3,9]] > 解法: 解法1 : 投影法 時間複雜度$O(n^2)$ 解法2 : 區間合併法 */ int[] target = new int[]{1,6}; int[][] parts = new int[][]{{2,3},{1,2},{3,9}}; System.out.println(isInner1(target,parts)); System.out.println(isInner2(target,parts)); } /** 解法1 : 投影法 用一個數組模擬x軸,然後進行投影。 */ public static boolean isInner1(int[] target,int[][] parts){ int max = Integer.MIN_VALUE; for(int[] part:parts) for(int i:part) max=Math.max(max,i); int[] arr = new int[max+1]; for(int[] part:parts) for(int i=part[0];i<=part[1];i++) arr[i] = 1; for(int i = target[0];i<=target[1];i++) if(arr[i] == 0) return false; return true; } /** 解法2:合併區間 */ public static boolean isInner2(int[] target,int[][] parts){ int[][] arr = merge(parts); for(int[] part:arr) if(target[0] >= part[0] && target[1] <= part[1]) return true; return false; } public static int[][] merge(int[][] parts) { if (parts.length == 0) { return new int[0][2]; } Arrays.sort(parts,(o1,o2)->(o1[0] - o2[0])); List<int[]> merged = new ArrayList<int[]>(); for (int i = 0; i < parts.length; ++i) { int L = parts[i][0], R = parts[i][1]; if (merged.size() == 0 || merged.get(merged.size() - 1)[1] < L) { merged.add(new int[]{L, R}); } else { merged.get(merged.size() - 1)[1] = Math.max(merged.get(merged.size() - 1)[1], R); } } return merged.toArray(new int[merged.size()][]); } /** 拓展問題: 如何處理二維空間中的覆蓋問題?例如在Windows桌面上有若干視窗,如何判斷某一視窗是否完全被其他視窗覆蓋? answer: 就檢查一次長的區間是否被包含&&寬的長度區間是否被包含 */ }