zoukankan      html  css  js  c++  java
  • [Daily Coding Problem 290] Quxes Transformation

    On a mysterious island there are creatures known as Quxes which come in three colors: red, green, and blue. One power of the Qux is that if two of them are standing next to each other, they can transform into a single creature of the third color.

    Given N Quxes standing in a line, determine the smallest number of them remaining after any possible sequence of such transformations.

    For example, given the input ['R', 'G', 'B', 'G', 'B'], it is possible to end up with a single Qux through the following steps:

            Arrangement       |   Change
    ----------------------------------------
    ['R', 'G', 'B', 'G', 'B'] | (R, G) -> B
    ['B', 'B', 'G', 'B']      | (B, G) -> R
    ['B', 'R', 'B']           | (R, B) -> G
    ['B', 'G']                | (B, G) -> R
    ['R']                     |


    One way to solve this problem would be to try every possible sequence of transformations, and find the one that results in the smallest result.

    We can make this approach a little more methodical using recursion. For a given starting array, any transformation will turn the array into a new one with one fewer element, to which we can then re-apply our function. At each step of our process we can apply our function to all possible transformation and return the minimal outcome.

    The base case for this recursion is when all the Quxes in the line are the same color. In this case no moves are possible, so we must return the length of the line.

    For any array, there may be N - 1 possible transformations to apply, where N is the length of the array. As a result, we may need to call our function (N - 1) * (N - 2) * ... * 1 times, as the number of possible sequences proliferates. The time of complexity of this algorithm is therefore O(N!).

    Fortunately, we can use math to find a more elegant solution.

    First, recall that any integer must be either even or odd, a quality known as its parity. Now suppose we have three integers (a, b, c), representing the number of Quxes of each color. For any given configuration there will be four cases:

    • (a) These numbers are all even
    • (b) These numbers are all odd
    • (c) Two are even, and one is odd
    • (d) Two are odd, and one is even

    The cases fall into two groups: either the parity of all the integers will be the same (a and b), or the parity will break down into two numbers on one side, and one on the other (c and d).

    Now note that for any transformation, we reduce the count of two colors by one, and increase the value of the other by one. For example, in the change (R, G) -> B, we decrement the number of red and green Quxes and increment the number of blue ones. Crucially, this does not change which of the two above groups the line falls into. In other words, a Qux line will always be alternating between cases a and b, or between c and d, but never both.

    What, then, is the best possible outcome for each group? For the first group, this will be either (2, 0, 0)(0, 2, 0), or (0, 0, 2). That is, once we reach a point where we have two Quxes of one color and none of any other color, no new transformations are possible. And since it is impossible to remove all Quxes from the line, these are the equal-parity formations with the lowest sum.

    Analogously, the best outcome for a split-parity group will be (1, 0, 0)(0, 1, 0), or (0, 0, 1).

    With some care we can show that as long as our initial line does not consist of all Quxes of the same color, we can continually apply transformations to get to one of these base cases. As a result, our solution will simply be the following:

    • If all Quxes begin as the same color, return the length of the line.
    • If the parities of each color are equal, return 2.
    • If the parities of each color are split, return 1.
        public int minLeft(char[] quxes) {
            int red = 0, green = 0, blue = 0;
            for(char c : quxes) {
                switch (c) {
                    case 'R':
                        red++;
                        break;
                    case 'G':
                        green++;
                        break;
                    case 'B':
                        blue++;
                        break;
                }
            }
            if(red == quxes.length || green == quxes.length || blue == quxes.length) {
                return quxes.length;
            }
            if(red % 2 == green % 2 && red % 2 == blue % 2) {
                return 2;
            }
            return 1;
        }

    The time complexity of this solution is O(N), since all we need to do is count up the Qux colors and calculate each count mod 2.

  • 相关阅读:
    双谷人才财务管理(3)
    远程服务器上个人目录下python路径设置
    ubnutu16安装谷歌浏览器
    一个数组除了一个元素只出现一次,其他元素全都出现了三次,输出出现一次的元素
    一个整型数组里除了一个数字之外,其它的数字都出现了两次。请写程序找出这个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。
    滑动窗口的最大值
    360
    拼多多2018/8/5算法工程师笔试
    最小的K个数 C++(BFPRT,堆排序)
    CCF201312-3 最大的矩形(100分)
  • 原文地址:https://www.cnblogs.com/lz87/p/11518225.html
Copyright © 2011-2022 走看看