1. 程式人生 > 實用技巧 >2.19 區間重合判斷

2.19 區間重合判斷

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:
		就檢查一次長的區間是否被包含&&寬的長度區間是否被包含
	*/
}