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

K Inverse Pair Array #3

Open
csujedihy opened this issue Jun 27, 2017 · 0 comments
Open

K Inverse Pair Array #3

csujedihy opened this issue Jun 27, 2017 · 0 comments
Labels

Comments

@csujedihy
Copy link
Owner

Idea:

You can just write down some the cases from 1 to 4 and you will find the pattern which is actually combinations.
Like when i = 4, you can just insert 4 to all the cases in a proper position when i = 3 to get the number of results when i=4.
Note that i limits the number of places you can do the insertion. If i = 5, there is only 5 places you can insert.
So you start from i = 0 as base case and you can get the final result at the end.

This is what we get from the above conclusion.

dp[i][j] = dp[i-1][j - i + 1] + dp[i-1][j - i + 2] + ... + dp[i-1][j]

But if you want to get your solution accepted in Python, then you need more optimization (BTW: I think is unfair since C++'s solution can pass it).
Actually, the above formula does have lots of redundant computation. As you can see, fordp[i][j]and dp[i][j-1], we may use dp[i-1][j-1], dp[i-1][j-2],...,dp[i-1][j-i+1] twice. Thus, I rewrite the formula as follows.

dp[i][j] = dp[i][j-1] + dp[i-1][j] - (if j - i >= 0: dp[i-1][j-i] else: 0)

It works like a sliding window, adding dp[i-1][j] to dp[i][j-1] and then reducing dp[i-1][j-i] if applicable to remain a sliding window whose size is i.

O(nk) space solution

class Solution(object):
    def kInversePairs(self, n, k):
        """
        :type n: int
        :type k: int
        :rtype: int
        """
        MOD = 10**9 + 7
        upper = n * (n - 1) / 2
        if k == 0 or k == upper:
            return 1
        if k > upper:
            return 0
        dp = [[0] * (k + 1) for _ in range(n + 1)]
        dp[0][0] = 1
        for i in range(1, n + 1):
            dp[i][0] = 1
            for j in range(k + 1):
                dp[i][j] = (dp[i][j-1] + dp[i-1][j]) % MOD
                if j - i >= 0:
                    dp[i][j] = (dp[i][j] - dp[i - 1][j - i] + MOD) % MOD
        return dp[n][k]

O(k) space solution

class Solution(object):
    def kInversePairs(self, n, k):
        """
        :type n: int
        :type k: int
        :rtype: int
        """
        MOD = 10**9 + 7
        upper = n * (n - 1) / 2
        if k == 0 or k == upper:
            return 1
        if k > upper:
            return 0
        dp = [0] * (k + 1)
        dp[0] = 1
        for i in range(1, n + 1):
            temp =[1] + [0] * k
            for j in range(k + 1):
                temp[j] = (temp[j-1] + dp[j]) % MOD
                if j - i >= 0:
                    temp[j] = (temp[j] - dp[j - i]) % MOD
            dp = temp
        return dp[k]
@csujedihy csujedihy added the Note label Jun 27, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant