Optimal Partition Array


http://www.1point3acres.com/bbs/thread-144544-1-1.html
Given a list of integer items, we want to partition the items into at most N non-overlapping, consecutive bins, in a way that minimizes the maximum number of items in any bin.
For example, suppose we are given the items (5, 2, 3, 6, 1, 6), and we want 3bins. We can optimally partition these as follows:
n < 3: 1, 2 (2 items)
3 <= n < 6: 3, 5 (2 items)
6 <= n: 6, 6 (2 items)
Every bin has 2 items, so we can’t do any better than that.
Your task: write a program to partition a set of input items.
Example input:
N = 3
5
2

6

6
Example output:
12
35
66 

1. sort;
2. 输出相同元素的个数,组成一个新的array;
3. 针对新的array做minmax partition;
    minmax partition核心思想是二分法+贪心:
        1. 找到每个bin中元素和(新的这个array里一个bin中的所有“元素和”表明原始array中对应bin中元素的个数)的可能区间范围;
            1. min是新的array中最大值;
            2. max是新的array中所有元素的和;
        2. 二分搜索这个区间中的值v是否能够得到满足题意的划分,判断时只需要贪心地从左向右添加元素直至达到v;
  1. class OptimalPartition {

  2.     public List<List<Integer>> partitions(int[] nums, int k) {
  3.         List<List<Integer>> result = new ArrayList<>();
  4.         if (nums == null || nums.length == 0) return result;
  5.         int n = nums.length;

  6.         // Sort array, then collapse it.
  7.         Arrays.sort(nums);
  8.         List<Integer> collapsed = new ArrayList<>();
  9.         int[] info = collapse(nums, collapsed);
  10.         int max = info[0], sum = info[1];

  11.         // Use binary search to find appropriate value;
  12.         int rangeMin = max; // The minimum value of number of elements in a given bin 
  13.         int rangeMax = sum; // The maximum value of number of elements in a given bin
  14.         int num = binarySearch(collapsed, rangeMin, rangeMax, k);

  15.         // Finish the partition using 'num';
  16.         int i = 0;
  17.         while (i < n) {
  18.             List<Integer> item = new ArrayList<>();
  19.             int counter = 0;
  20.             while (counter++ < num && i<n) {
  21.                 item.add(nums[i++]);
  22.             }
  23.             result.add(item);
  24.         }
  25.         return result;
  26.     }

  27.     /* After sorting the original array, convert it into another array, element of which 
  28.      * is the number of consecutive equal number.
  29.      */
  30.     private int[] collapse(int[] nums, List<Integer> collapsed) {
  31.         int prev = nums[0];
  32.         int counter = 1;
  33.         int sum = 0, max = 0;
  34.         for (int i=1; i<nums.length; ++i) {
  35.             if (nums[i] == prev) counter++;
  36.             else {
  37.                 collapsed.add(counter);
  38.                 max = Math.max(max, counter);
  39.                 sum+=counter;
  40.                 counter = 1;
  41.                 prev = nums[i];
  42.             }
  43.         }
  44.         collapsed.add(counter);
  45.         max = Math.max(max, counter);
  46.         sum+=counter;
  47.         return new int[] {max, sum};
  48.    }

  49.     private int binarySearch(List<Integer> collapsed, int start, int end, int k) {
  50.         if (start > end) return -1;
  51.         int mid = start + (end - start)/2;
  52.         if (partition(collapsed, mid, k)) {
  53.             int left = binarySearch(collapsed, start, mid-1, k);
  54.             if (left != -1) return left;
  55.             return mid;
  56.         }
  57.         return binarySearch(collapsed, mid+1, end, k);
  58.     }

  59.     // Greedily allocate element from left to right using given 'maximum number of elements in a bin'
  60.     private boolean partition(List<Integer> collapsed, int max, int k) {
  61.         int n = collapsed.size();
  62.         int counter = 0;
  63.         int partitionNum = 0;
  64.         for (int i=0; i<n; ++i) {
  65.             if (counter+collapsed.get(i)<=max) {
  66.                 counter += collapsed.get(i);
  67.             } else {
  68.                 counter = 0;
  69.                 i--;
  70.                 partitionNum++;
  71.             }
  72.         }
  73.         partitionNum++;
  74.         return partitionNum<=k;
  75.     }

  76.     public static void main(String[] args) {
  77.         OptimalPartition o = new OptimalPartition();
  78.         for (List<Integer> part: o.partitions(new int[] {5, 2, 3, 6, 1, 6}, 3)) {
  79.             System.out.println(part);
  80.         }
  81.         for (List<Integer> part: o.partitions(new int[] {1, 1, 1, 1, 1, 1}, 3)) {
  82.             System.out.println(part);
  83.         }
  84.         for (List<Integer> part: o.partitions(new int[] {1, 1, 1, 1, 2, 2, 3}, 2)) {
  85.             System.out.println(part);
  86.         }
  87.     }
  88. }

DP应该也可以。
先记录每个元素的出现次数(key, count), 然后按照key排序存一个数组A
用L[i,k]记录用最优解将第0-i个元素放到k个bin里时的最后一个bin包含的元素个数,G[i,k]记录最大bin里的元素个数
更新L[i,k]和G[i,k]要做以下判断
如果L[i-1, k]+A[i]<=G[i-1,k],那么最优放法就是L[i,k]=L[i-1,k]+A[i], G[i,k]=G[i-1,k]
如果L[i-1,k]+A[i]>G[i-1,k],那么就可能有两种放法,最优放法要取其中之一:
方法1: 前面i-1个元素放到k个bin里,然后元素i也放到bin k里,bin k的元素总数是 s1 = L[i-1,k]+A[k]
方法2: 前面i-1个元素放到k-1个bin里,然后元素i单独放到bin k里, bin k的元素总数是 s2 = A[k]
如果s1<max(s2,G[i-1,k-1]),那就选方法1,L[i,k] = L[i-1,k]+A[k], G[i,k] = L[i,k]
如果s1>max(s2, G[i-1, k-1]),那就选方法2, L[i,k] = A[k], G[i,k] = max(L[i,k], G[i-1, k-1])
如果s1==max(s2, G[i-1, k-1]),那就随便选1或者2

最后要求的就是G[m-1, n-1], m是distinct元素的个数,n是bin的个数

    def placement(self, nums, n):
        
        numbers = {key:nums.count(key) for key in nums}
        numbers = [(key, numbers[key]) for key in numbers]
        numbers.sort()

        A = [item[1] for item in numbers]
        
        if len(numbers)<=n:
            return max(A)

        L = [[0]*n for _ in range(len(A))]
        G = [[0]*n for _ in range(len(A))]

        L[0][0] = A[0]
        G[0][0] = A[0]
        for i in range(1, len(A)):
            L[0] = L[i-1][0] + A
            G[0] = L[0]

        for i in range(len(A)):
            if i>=n:
                break
            L = A
            G = max(A[:i+1])

        for i in range(len(A)):
            for j in range(i+1, n):
                L[j] = 0
                G[j] = G

        for i in range(1,len(A)):
            for j in range(1,i):
                if j>=n:
                    break
                tmp = L[i-1][j] + A
                if tmp<=G[i-1][j]:
                    L[j] = tmp
                    G[j] = G[i-1][j]
                elif tmp<=max(G[i-1][j-1], A):
                    L[j] = tmp
                    G[j] = G[i-1][j]
                else:
                    L[j] = A
                    G[j] = max(G[i-1][j-1], A)

        return G[len(A)-1][n-1]

sol = Solution()
nums = [1,1,1,1,1,1]
result = sol.placement(nums, 3)
print(result)

Labels

LeetCode (1432) GeeksforGeeks (1122) LeetCode - Review (1067) Review (882) Algorithm (668) to-do (609) Classic Algorithm (270) Google Interview (237) Classic Interview (222) Dynamic Programming (220) DP (186) Bit Algorithms (145) POJ (141) Math (137) Tree (132) LeetCode - Phone (129) EPI (122) Cracking Coding Interview (119) DFS (115) Difficult Algorithm (115) Lintcode (115) Different Solutions (110) Smart Algorithm (104) Binary Search (96) BFS (91) HackerRank (90) Binary Tree (86) Hard (79) Two Pointers (78) Stack (76) Company-Facebook (75) BST (72) Graph Algorithm (72) Time Complexity (69) Greedy Algorithm (68) Interval (63) Company - Google (62) Geometry Algorithm (61) Interview Corner (61) LeetCode - Extended (61) Union-Find (60) Trie (58) Advanced Data Structure (56) List (56) Priority Queue (53) Codility (52) ComProGuide (50) LeetCode Hard (50) Matrix (50) Bisection (48) Segment Tree (48) Sliding Window (48) USACO (46) Space Optimization (45) Company-Airbnb (41) Greedy (41) Mathematical Algorithm (41) Tree - Post-Order (41) ACM-ICPC (40) Algorithm Interview (40) Data Structure Design (40) Graph (40) Backtracking (39) Data Structure (39) Jobdu (39) Random (39) Codeforces (38) Knapsack (38) LeetCode - DP (38) Recursive Algorithm (38) String Algorithm (38) TopCoder (38) Sort (37) Introduction to Algorithms (36) Pre-Sort (36) Beauty of Programming (35) Must Known (34) Binary Search Tree (33) Follow Up (33) prismoskills (33) Palindrome (32) Permutation (31) Array (30) Google Code Jam (30) HDU (30) Array O(N) (29) Logic Thinking (29) Monotonic Stack (29) Puzzles (29) Code - Detail (27) Company-Zenefits (27) Microsoft 100 - July (27) Queue (27) Binary Indexed Trees (26) TreeMap (26) to-do-must (26) 1point3acres (25) GeeksQuiz (25) Merge Sort (25) Reverse Thinking (25) hihocoder (25) Company - LinkedIn (24) Hash (24) High Frequency (24) Summary (24) Divide and Conquer (23) Proof (23) Game Theory (22) Topological Sort (22) Lintcode - Review (21) Tree - Modification (21) Algorithm Game (20) CareerCup (20) Company - Twitter (20) DFS + Review (20) DP - Relation (20) Brain Teaser (19) DP - Tree (19) Left and Right Array (19) O(N) (19) Sweep Line (19) UVA (19) DP - Bit Masking (18) LeetCode - Thinking (18) KMP (17) LeetCode - TODO (17) Probabilities (17) Simulation (17) String Search (17) Codercareer (16) Company-Uber (16) Iterator (16) Number (16) O(1) Space (16) Shortest Path (16) itint5 (16) DFS+Cache (15) Dijkstra (15) Euclidean GCD (15) Heap (15) LeetCode - Hard (15) Majority (15) Number Theory (15) Rolling Hash (15) Tree Traversal (15) Brute Force (14) Bucket Sort (14) DP - Knapsack (14) DP - Probability (14) Difficult (14) Fast Power Algorithm (14) Pattern (14) Prefix Sum (14) TreeSet (14) Algorithm Videos (13) Amazon Interview (13) Basic Algorithm (13) Codechef (13) Combination (13) Computational Geometry (13) DP - Digit (13) LCA (13) LeetCode - DFS (13) Linked List (13) Long Increasing Sequence(LIS) (13) Math-Divisible (13) Reservoir Sampling (13) mitbbs (13) Algorithm - How To (12) Company - Microsoft (12) DP - Interval (12) DP - Multiple Relation (12) DP - Relation Optimization (12) LeetCode - Classic (12) Level Order Traversal (12) Prime (12) Pruning (12) Reconstruct Tree (12) Thinking (12) X Sum (12) AOJ (11) Bit Mask (11) Company-Snapchat (11) DP - Space Optimization (11) Dequeue (11) Graph DFS (11) MinMax (11) Miscs (11) Princeton (11) Quick Sort (11) Stack - Tree (11) 尺取法 (11) 挑战程序设计竞赛 (11) Coin Change (10) DFS+Backtracking (10) Facebook Hacker Cup (10) Fast Slow Pointers (10) HackerRank Easy (10) Interval Tree (10) Limited Range (10) Matrix - Traverse (10) Monotone Queue (10) SPOJ (10) Starting Point (10) States (10) Stock (10) Theory (10) Tutorialhorizon (10) Kadane - Extended (9) Mathblog (9) Max-Min Flow (9) Maze (9) Median (9) O(32N) (9) Quick Select (9) Stack Overflow (9) System Design (9) Tree - Conversion (9) Use XOR (9) Book Notes (8) Company-Amazon (8) DFS+BFS (8) DP - States (8) Expression (8) Longest Common Subsequence(LCS) (8) One Pass (8) Quadtrees (8) Traversal Once (8) Trie - Suffix (8) 穷竭搜索 (8) Algorithm Problem List (7) All Sub (7) Catalan Number (7) Cycle (7) DP - Cases (7) Facebook Interview (7) Fibonacci Numbers (7) Flood fill (7) Game Nim (7) Graph BFS (7) HackerRank Difficult (7) Hackerearth (7) Inversion (7) Kadane’s Algorithm (7) Manacher (7) Morris Traversal (7) Multiple Data Structures (7) Normalized Key (7) O(XN) (7) Radix Sort (7) Recursion (7) Sampling (7) Suffix Array (7) Tech-Queries (7) Tree - Serialization (7) Tree DP (7) Trie - Bit (7) 蓝桥杯 (7) Algorithm - Brain Teaser (6) BFS - Priority Queue (6) BFS - Unusual (6) Classic Data Structure Impl (6) DP - 2D (6) DP - Monotone Queue (6) DP - Unusual (6) DP-Space Optimization (6) Dutch Flag (6) How To (6) Interviewstreet (6) Knapsack - MultiplePack (6) Local MinMax (6) MST (6) Minimum Spanning Tree (6) Number - Reach (6) Parentheses (6) Pre-Sum (6) Probability (6) Programming Pearls (6) Rabin-Karp (6) Reverse (6) Scan from right (6) Schedule (6) Stream (6) Subset Sum (6) TSP (6) Xpost (6) n00tc0d3r (6) reddit (6) AI (5) Abbreviation (5) Anagram (5) Art Of Programming-July (5) Assumption (5) Bellman Ford (5) Big Data (5) Code - Solid (5) Code Kata (5) Codility-lessons (5) Coding (5) Company - WMware (5) Convex Hull (5) Crazyforcode (5) DFS - Multiple (5) DFS+DP (5) DP - Multi-Dimension (5) DP-Multiple Relation (5) Eulerian Cycle (5) Graph - Unusual (5) Graph Cycle (5) Hash Strategy (5) Immutability (5) Java (5) LogN (5) Manhattan Distance (5) Matrix Chain Multiplication (5) N Queens (5) Pre-Sort: Index (5) Quick Partition (5) Quora (5) Randomized Algorithms (5) Resources (5) Robot (5) SPFA(Shortest Path Faster Algorithm) (5) Shuffle (5) Sieve of Eratosthenes (5) Strongly Connected Components (5) Subarray Sum (5) Sudoku (5) Suffix Tree (5) Swap (5) Threaded (5) Tree - Creation (5) Warshall Floyd (5) Word Search (5) jiuzhang (5)

Popular Posts