667. Beautiful Arrangement II-- 類比526 但不能用back tracking
阿新 • • 發佈:2018-11-16
get system case dex 得出 res bool 數組 back
667 是很坑爹的一個題目,乍一看和 526 如出一轍,
526. Beautiful Arrangement 題意: 構造 [1,n]的排列,讓每個 a[index] % index ==0 或者 index %a[index] ==0, 基本和 46 題一樣,就是構造排列。
667題意:
給定兩個整數n
和k
,構建一個n
個元素數組,數組要滿足一下要求:
假設數組[a1,a2....an]
那麽[|a2-a1|,|a3-a2|.....]
包含k
個不同的整數。如果有多個數組輸出任意一個數組。1<=k<n<=10000
看到題目誤以為和526 類似, 準備用back tracking 構造, 但復雜度為 n! , 如果數據範圍為 1000, 那麽 1000! 不管如何剪枝,都會TLE,TLE的code 如下,寫的竟然有板有眼。
class Solution { public int[] constructArray(int n, int k) { if(n-1<k) return new int[0]; int[] nums = new int[n]; List<Integer> result = new ArrayList<>(); for(int i=0; i<n; i++){ nums[i] = i+1; } dfs(result, nums,new boolean[n], k, new HashSet<>()); for(int i=0; i<result.size(); i++) nums[i] = result.get(i); return nums; } private boolean dfs(List<Integer> result, int[] nums, boolean[] used, int k , Set<Integer> set){ if(result.size() == nums.length && set.size() == k){ System.out.println(result);return true; } if(result.size() >= nums.length) return false; boolean flag = false; for(int i=0; i<nums.length; i++){ if(!used[i]){ int size = result.size(); int abs = 0; boolean added = false; if(result.size()>0){ abs = Math.abs(result.get(size-1) - nums[i]); if(!set.contains(abs) && set.size()+1 >k) { continue;} set.add(abs); added = true; } result.add(nums[i]); used[i] = true; flag = flag || dfs(result,nums,used,k,set); if(flag) return true; result.remove(result.size()-1); used[i] = false; if(added) set.remove(abs); } } return flag; } }
仔細分析一下題目, n 個數 可以排不同差值的組合, 最大 n-1, 最小為1, 所以範圍為 [1~n-1], 如果 K > N-1 顯然不可解。
比如 n=9, k=5
可以構造 : 1,9,2,8, + 3,4,5,6,7
n=9,k=4, 可以構造: 1,9,2 + [8,7,6,5,4,3]
假設 left = 1, right = n
對於 K , 可以先放k-1 個數來構造, 1,n,2,n-1。。。 , 剩下的數字 遞增或者遞減即可
觀察上面的case 可以得出 k為odd 時, 接下來 數字為 從left 遞增, k為even 時,接下來數字為從right 遞減,code 如下, 復雜度為 o(n):
class Solution { public int[] constructArray(int n, int k) { if(k>n-1) return null; int[] result = new int[n]; int left =1; int right = n; int cons = k-1; for(int i=0;i<n; i++){ if(cons>=0){ if(i%2 ==0) result[i] = right--; else result[i] = left++; cons--; } else { if(k%2==0) { result[i] = left++; } else result[i] = right--; } } return result; } }
667. Beautiful Arrangement II-- 類比526 但不能用back tracking