美文网首页
667. Beautiful Arrangement II

667. Beautiful Arrangement II

作者: Nancyberry | 来源:发表于2018-05-27 03:45 被阅读0次

    Description

    Given two integers n and k, you need to construct a list which contains n different positive integers ranging from 1 to n and obeys the following requirement:
    Suppose this list is [a1, a2, a3, ... , an], then the list [|a1 - a2|, |a2 - a3|, |a3 - a4|, ... , |an-1 - an|] has exactly k distinct integers.

    If there are multiple answers, print any of them.

    Example 1:

    Input: n = 3, k = 1
    Output: [1, 2, 3]
    Explanation: The [1, 2, 3] has three different positive integers ranging from 1 to 3, and the [1, 1] has exactly 1 distinct integer: 1.

    Example 2:

    Input: n = 3, k = 2
    Output: [1, 3, 2]
    Explanation: The [1, 3, 2] has three different positive integers ranging from 1 to 3, and the [2, 1] has exactly 2 distinct integers: 1 and 2.

    Note:

    1. The n and k are in the range 1 <= k < n <= 104.

    Solution

    Backtracking, O(n ^ 2), S(n) (TLE)

    典型的回溯思路。

    class Solution {
        public int[] constructArray(int n, int k) {
            int[] nums = new int[n];
            for (int i = 0; i < n; ++i) {
                nums[i] = i + 1;
            }
            backtracking(nums, 0, new int[n], 0, k);
            return nums;
        }
        
        private boolean backtracking(int[] nums, int start, int[] counts, int unique, int k) {
            if (start >= nums.length && unique == k) {
                return true;
            }
            
            if (unique >= k) {
                return false;
            }
            
            for (int i = start; i < nums.length; ++i) {
                swap(nums, start, i);
                
                if (start > 0) {
                    int delta = Math.abs(nums[start] - nums[start - 1]);
                    if (++counts[delta] == 1) {
                        ++unique;
                    }
                }
                
                if (backtracking(nums, start + 1, counts, unique, k)) {
                    return true;
                }
                
                if (start > 0) {
                    int delta = Math.abs(nums[start] - nums[start - 1]);
                    if (--counts[delta] == 0) {
                        --unique;
                    }
                }
                swap(nums, start, i);
            }
            
            return false;
        }
        
        private void swap(int[] nums, int i, int j) {
            int tmp = nums[i];
            nums[i] = nums[j];
            nums[j] = tmp;
        }
    }
    

    Construct, O(n), S(1)

    这道题的解法其实是有规律可循的:

    • k = 1: 序列为{1, 2, ..., n - 1, n}
    • k = n - 1: 序列为{1, n, 2, n - 1, ..., n / 2 - 1, n / 2},这样delta就是{n-1, n-2, n-3, ..., 1},unique count = n - 1
      对n个数字来说,可以构成最少1个最多n - 1个unique delta的序列。

    那么如果想要生成unique number为k的n个数序列,把数字分成两部分即可:

    • part 1: n - k - 1个数字:{1, 2, ..., n - k - 1}
    • part 2: k + 1个数字:{1, k, 2, k - 1, ..., k / 2 - 1, k / 2},所有数字再加上初始的increase为n - k - 1。这部分序列生成,要依靠头尾拼接数组来做。

    然后将两部分拼接起来,返回即可。

    class Solution {
        public int[] constructArray(int n, int k) {
            int[] nums = new int[n];
            int pos = 0;
            
            for (int i = 1; i < n - k; ++i) {
                nums[pos++] = i;
            }
            
            for (int i = 0; i <= k; ++i) {
                nums[pos++] = i % 2 == 0 ?
                    i / 2 + n - k : n - i / 2;
            }
            
            return nums;
        }
    }
    

    相关文章

      网友评论

          本文标题:667. Beautiful Arrangement II

          本文链接:https://www.haomeiwen.com/subject/jpgvjftx.html