【Lintcode】359. Make Equilateral Triangle

記錄演算法發表於2020-12-18

題目地址:

https://www.lintcode.com/problem/makeequilateraltriangle/description

給定一個長 n n n的正整數陣列 A A A,代表 n n n個木棍的長度。允許對於其中某些木棍進行切割,切出兩根新的木棍,但要求只能切出長度整數的木棍。問至少經過多少次切割,可以使得切完之後可以挑出 3 3 3根長度相同的木棍。題目保證 n ≥ 3 n\ge 3 n3

首先容易知道答案最多是 2 2 2。顯然答案等於 0 0 0當且僅當存在同一個數重複了 3 3 3次,而答案等於 1 1 1當且僅當上述條件不成立,並且或者某個數是另一個數的兩倍,或者某個數出現了兩次並且後面還有個更大的數。所以,可以先對 A A A從小到大排序,接著遍歷之。一開始初始化答案為 2 2 2。每次遍歷到 A [ i ] A[i] A[i]的時候,先數一下這個數出現了多少次,如果出現了不少於 3 3 3次則直接返回 0 0 0,如果出現了 2 2 2次,則看一下後面是否還有數,如果有則更新答案為 1 1 1;此外,如果 A [ i ] A[i] A[i]是偶數並且 A [ i ] / 2 A[i]/2 A[i]/2存在,則也更新答案為 1 1 1。迴圈結束了返回答案即可。程式碼如下:

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

public class Solution {
    /**
     * @param lengths: the lengths of sticks at the beginning.
     * @return: return the minimum number of cuts.
     */
    public int makeEquilateralTriangle(int[] lengths) {
        // write your code here.
        Arrays.sort(lengths);
        Set<Integer> set = new HashSet<>();
        int res = 2;
        for (int i = 0; i < lengths.length; i++) {
            int j = i;
            while (j < lengths.length && lengths[j] == lengths[i]) {
                j++;
            }
            
            if (j - i >= 3) {
                return 0;
            } else if (j - i == 2 && j < lengths.length) {
                res = 1;
            }
            
            if (lengths[i] % 2 == 0 && set.contains(lengths[i] / 2)) {
                res = 1;
            }
            
            set.add(lengths[i]);

			i = j - 1;
        }
        
        return res;
    }
}

時間複雜度 O ( n log ⁡ n ) O(n\log n) O(nlogn),空間複雜度 O ( n ) O(n) O(n)

相關文章