Lesson 6 question 4 NumberOfDiscIntersections

源地址

https://app.codility.com/programmers/lessons/6-sorting/number_of_disc_intersections/

NumberOfDiscIntersections(圓盤交集數)

我們在一個平面上畫N個圓盤,標記爲0到N-1 ,一個含有N個非負整數的數組A,表示這些圓盤的半徑,第J個圓盤,他的圓心在 (J, 0) ,並且半徑爲A[J].
我們說圓盤J和圓盤K有交集,如果J≠K,並且這兩個圓盤至少有一個共同的點(假定圓盤包括他們的邊).
比如N=6、並有如下的數組A:

A[0] = 1
A[1] = 5
A[2] = 2
A[3] = 1
A[4] = 4
A[5] = 0

在這裏插入圖片描述
有11個圓盤交集(非排序):

  • 1 和4有交集,並且都和其他所有的圓盤都有
  • 2 和 0 以及4 有交集

寫一個函數

	class Solution { 
		public int solution(int[] A); 
	}

給定一個代表N個圓盤的數組A,返回有交集的圓盤的數量.如果交集數量大於10,000,000,返回-1.
比如上面給出的數組A,函數返回11.
假定:

  • N是範圍在 [0…100,000]的整數
  • A中的每個元素都是範圍在[0…2,147,483,647]的整數

第一步

有A個圓疊加時,兩兩配對的計算公式爲 (A * (A-1) )/ 2(高中集合論?)
用兩個長度爲N的數組,分別記錄到各個圓心的左邊界和右邊界,然後遍歷圓心,計算出到每個圓心座標時新增加的圓的數量.
注意半徑可能爲Integer.Max_Value,需要考慮溢出的情況.

	public int solution(int[] A) {
        int N = A.length;
        if (N == 0)
            return 0;
        int[] leftArr = new int[N];
        int[] rightArr = new int[N];
        for (int i = 0; i < N; i++) {
            int left = Math.max(0, i - A[i]);
            leftArr[left]++;
            int right = Math.min(N - 1, i + A[i]);
            if (i > Integer.MAX_VALUE - A[i]) {
                right = N - 1;
            }
            rightArr[right]++;
        }

        int level = 0;
        int result = 0;
        for (int i = 0; i < N; i++) {
            if (leftArr[i] > 0) {
                int num = level * leftArr[i] + (leftArr[i] * (leftArr[i] - 1)) / 2;
                result += num;
                if (result > 10000000)
                    return -1;
            }
            level = level - rightArr[i] + leftArr[i];
        }

        return result;
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章