Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[LeetCode] 484. Find Permutation #484

Open
grandyang opened this issue May 30, 2019 · 0 comments
Open

[LeetCode] 484. Find Permutation #484

grandyang opened this issue May 30, 2019 · 0 comments

Comments

@grandyang
Copy link
Owner

grandyang commented May 30, 2019

 

By now, you are given a secret signature consisting of character 'D' and 'I'. 'D' represents a decreasing relationship between two numbers, 'I' represents an increasing relationship between two numbers. And our secret signaturewas constructed by a special integer array, which contains uniquely all the different number from 1 to n (n is the length of the secret signature plus 1). For example, the secret signature "DI" can be constructed by array [2,1,3] or [3,1,2], but won't be constructed by array [3,2,4] or [2,1,3,4], which are both illegal constructing special string that can't represent the "DI" secret signature.

On the other hand, now your job is to find the lexicographically smallest permutation of [1, 2, ... n] could refer to the given secret signature in the input.

Example 1:

Input: "I"
Output: [1,2]
Explanation: [1,2] is the only legal initial spectial string can construct secret signature "I", where the number 1 and 2 construct an increasing relationship.

 

Example 2:

Input: "DI"
Output: [2,1,3]
Explanation: Both [2,1,3] and [3,1,2] can construct the secret signature "DI",   
but since we want to find the one with the smallest lexicographical permutation, you need to output [2,1,3]

 

Note:

  • The input string will only contain the character 'D' and 'I'.
  • The length of input string is a positive integer and will not exceed 10,000

 

这道题给了我们一个由D和I两个字符组成的字符串,分别表示对应位置的升序和降序,要我们根据这个字符串生成对应的数字字符串。由于受名字中的permutation的影响,感觉做法应该是找出所有的全排列然后逐个数字验证,这种方法十有八九无法通过OJ。其实这题用贪婪算法最为简单,我们来看一个例子:

D D I I D I

1 2 3 4 5 6 7

3 2 1 4 6 5 7

我们不难看出,只有D对应的位置附近的数字才需要变换,而且变换方法就是倒置一下字符串,我们要做的就是通过D的位置来确定需要倒置的子字符串的起始位置和长度即可。通过观察,我们需要记录D的起始位置i,还有D的连续个数k,那么我们只需要在数组中倒置[i, i+k]之间的数字即可,根据上述思路可以写出代码如下:

 

解法一:

class Solution {
public:
    vector<int> findPermutation(string s) {
        int n = s.size();
        vector<int> res(n + 1);
        for (int i = 0; i < n + 1; ++i) res[i] = i + 1;
        for (int i = 0; i < n; ++i) {
            if (s[i] != 'D') continue;
            int j = i;
            while (s[i] == 'D' && i < n) ++i;
            reverse(res.begin() + j, res.begin() + i + 1);
            --i;
        }
        return res;
    }
};

 

下面这种方法没有用到数组倒置,而是根据情况来往结果res中加入正确顺序的数字,我们遍历s字符串,遇到D直接跳过,遇到I进行处理,我们每次先记录下结果res的长度size,然后从i+1的位置开始往size遍历,将数字加入结果res中即可,参见代码如下:

 

解法二:

class Solution {
public:
    vector<int> findPermutation(string s) {
        vector<int> res;
        for (int i = 0; i < s.size() + 1; ++i) {
            if (i == s.size() || s[i] == 'I') {
                int size = res.size();
                for (int j = i + 1; j > size; --j) {
                    res.push_back(j);
                }
            }
        }
        return res;
    }
};

 

类似题目:

Palindrome Permutation II

Palindrome Permutation

Permutation Sequence

Permutations II

Permutations

Next Permutation

 

参考资料:

https://leetcode.com/problems/find-permutation/

https://leetcode.com/problems/find-permutation/discuss/96644/c-simple-solution-in-72ms-and-9-lines

https://leetcode.com/problems/find-permutation/discuss/96663/greedy-on-java-solution-with-explanation

https://leetcode.com/problems/find-permutation/discuss/96613/java-on-clean-solution-easy-to-understand

 

LeetCode All in One 题目讲解汇总(持续更新中...)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant