Skip to content

Commit

Permalink
fixed texts
Browse files Browse the repository at this point in the history
  • Loading branch information
joric committed Jul 26, 2019
1 parent df5e0e2 commit 5554065
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 53 deletions.
46 changes: 29 additions & 17 deletions programming/backtracking/combination-sum-ii.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,34 @@
https://www.interviewbit.com/problems/combination-sum-ii


e integers.
Elements in a combination (a1, a2, … , ak) must be in non-descending order. (ie, a1 ≤ a2 ≤ … ≤ ak).
The solution set must not contain duplicate combinations.
Example :
Given a collection of candidate numbers (C) and a target number (T),
find all unique combinations in C where the candidate numbers sums to T.

Each number in C may only be used once in the combination.

1. Elements in a combination (a[1], a[2], ... , a[k]) must be in non-descending order.
(ie, a[1] <= a[2] <= ... a[k]).
2. The solution set must not contain duplicate combinations.

### Example

Given candidate set 10,1,2,7,6,1,5 and target 8,

v solution set is:
A solution set is:

```
[1, 7]
[1, 2, 5]
[2, 6]
[1, 1, 6]
Warning: DO NOT USE LItargetRvRY FUNCTION FOR GENERvTING COMtargetINvTIONS.
```

### Warning

DO NOT USE LIBRARY FUNCTION FOR GENERATING COMBINATIONS.

Example: itertools.combinations in python.

If you do, we will disqualify your submission retroactively and give you penalty points.


Expand All @@ -27,18 +40,17 @@ Think how can you use recursion with current index and target sum in order to ge

Also, you will have to take special care of those elements which can be overcounted as they are repeated.

Some elements can be repeated in the input set. Make sure you iterate over the number of occurrences
of those elements to make sure you are not counting the same combinations again.


Some elements can be repeated in the input set. Make sure you iterate over the number of occurrences of those elements to make sure you are not counting the same combinations again.

Once you do that, things are fairly straightforward. You make a recursive call with the remaining sum and make sure the indices are moving forward.
Once you do that, things are fairly straightforward. You make a recursive call with the remaining
sum and make sure the indices are moving forward.

## Solution

```cpp

// editorial
### Editorial

```cpp
void solve(vector<int> &A, int start, int end, vector<int> &temp, set<vector<int>> &ans, int sum, unordered_map<int, int> &used) {
if (sum < 0 || start > end) return;
if (sum == 0) {
Expand Down Expand Up @@ -73,9 +85,9 @@ vector<vector<int>> Solution::combinationSum(vector<int> &A, int B) {

return ret;
}

// mine

```
### Mine
```cpp
void backtracking(int start, vector<int> &row, int sum, vector<vector<int>> &res, vector<int> &v, int target) {
if (sum == target) {
res.push_back(row);
Expand Down Expand Up @@ -105,4 +117,4 @@ vector<vector<int>> Solution::combinationSum(vector<int> &v, int target) {
backtracking(0, row, 0, res, v, target);
return res;
}
```
```
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ Design an algorithm to find the maximum profit. You may complete as many transac

Example :
```
Input : [1 2 3]
Return : 2
Input: [1 2 3]
Return: 2
```

## Hint 1
Expand All @@ -32,7 +32,7 @@ Think and try to come up with a proof on the validity of the statement.

DP based solution:

Let Dp[i] = max profit you can gain in region (i,i+1,.,n).
Let Dp[i] = max profit you can gain in region (i,i+1,....,n).

Then Dp[i] = max(Dp[i+1],-A[i] + max( A[j]+Dp[j] st j > i ) )

Expand Down
26 changes: 15 additions & 11 deletions programming/dynamic-programming/regular-expression-ii.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,37 +47,41 @@ then refactor mercilessly to as clean and concise as possible!
This looks just like a straight forward string matching, isn't it? Couldn't we just match the pattern and the input string character by character? The question is, how to match a '*' ?

A natural way is to use a greedy approach; that is, we attempt to match the previous character as many as we can. Does this work? Let us look at some examples.

```
s = "abbbc"
p = "ab*c"
Assume we have matched the first 'a' on both s and p. When we see "b*" in p, we skip all b's in s. Since the last 'c' matches on both side, they both match.

```
Assume we have matched the first 'a' on both s and p. When we see `b*` in p, we skip all b's in s. Since the last 'c' matches on both side, they both match.
```
s = "ac"
p = "ab*c"
After the first 'a', we see that there is no b's to skip for "b*". We match the last 'c' on both side and conclude that they both match.
```
After the first 'a', we see that there is no b's to skip for `b*`. We match the last 'c' on both side and conclude that they both match.

It seems that being greedy is good. But how about this case?

```
s = "abbc"
p = "ab*bbc"
When we see "b*" in p, we would have skip all b's in s. They both should match, but we have no more b's to match. Therefore, the greedy approach fails in the above case.
```
When we see `b*` in p, we would have skip all b's in s. They both should match, but we have no more b's to match. Therefore, the greedy approach fails in the above case.

One might be tempted to think of a quick workaround. How about counting the number of consecutive b's in s? If it is smaller or equal to the number of consecutive b's after "b*" in p, we conclude they both match and continue from there. For the opposite, we conclude there is not a match.

This seem to solve the above problem, but how about this case:

```
s = "abcbcd"
p = "a.*c.*d"
Here, ".*" in p means repeat '.' 0 or more times. Since '.' can match any character, it is not clear how many times '.' should be repeated. Should the 'c' in p matches the first or second 'c' in s? Unfortunately, there is no way to tell without using some kind of exhaustive search.
```
Here, `.*` in p means repeat '.' 0 or more times. Since '.' can match any character, it is not clear how many times '.' should be repeated. Should the 'c' in p matches the first or second 'c' in s? Unfortunately, there is no way to tell without using some kind of exhaustive search.

We need some kind of backtracking mechanism such that when a matching fails, we return to the last successful matching state and attempt to match more characters in s with '*'. This approach leads naturally to recursion.

The recursion mainly breaks down elegantly to the following two cases:

If the next character of p is NOT '*', then it must match the current character of s. Continue pattern matching with the next character of both s and p.
If the next character of p is '*', then we do a brute force exhaustive matching of 0, 1, or more repeats of current character of p… Until we could not match any more characters.
You would need to consider the base case carefully too. That would be left as an exercise to the reader. :)
If the next character of p is NOT `*`, then it must match the current character of s. Continue pattern matching with the next character of both s and p.
If the next character of p is `*`, then we do a brute force exhaustive matching of 0, 1, or more repeats of current character of p Until we could not match any more characters.

You would need to consider the base case carefully too. That would be left as an exercise to the reader. :)


## Solution
Expand Down
20 changes: 12 additions & 8 deletions programming/dynamic-programming/scramble-string.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,16 @@ Lets first think of a bruteforce solution.
Obviously the 2 strings need to have the same number of characters and the same character set, otherwise the answer is definitely no.

In the bruteforce solution, we loop to find out the root of the tree.
Lets say the root is the ith character of string s1. Then the first part of s1 [0…i) can either match ( be a scrambled string of ) to s2[0…i) or s2(i+1 .. L]. Depending on which part s1[0…i) matches to, we match the remaining part of s1 to remaining part of s2. Just to clarify when we say s1 matches s2, we mean s1 is a scrambled string of s2.
Lets say the root is the ith character of string s1. Then the first part of s1 `[0...i)`
can either match ( be a scrambled string of ) to `s2[0...i)` or `s2(i+1 .. L]`.
Depending on which part `s1[0...i)` matches to, we match the remaining part of s1
to remaining part of s2. Just to clarify when we say s1 matches s2, we mean s1 is a scrambled string of s2.

We can write a very easy recursive function for this.

```
```java
public boolean isScramble(String s1, String s2) {
// CHECK BASE CASES HERE
if (s1 not anagram of s2) return false;

for(int i = 1; i < s1.length(); i++) { // i being the root position
Expand All @@ -76,17 +78,19 @@ public boolean isScramble(String s1, String s2) {
}
```

Now note that in any call for this function, the strings s1 and s2 would always be substrings of original S1 and S2. And we can specify substrings using startIndex, endIndex.
Now note that in any call for this function, the strings s1 and s2 would always be substrings
of original S1 and S2. And we can specify substrings using `startIndex, endIndex`.

Which means the recursive function can only be called with (startIndex1, endIndex1, startIndex2, endIndex2) possible tuples which can only take LLL*L possibilities roughly.
Which means the recursive function can only be called with
`(startIndex1, endIndex1, startIndex2, endIndex2)` possible tuples which can only take `L*L` possibilities roughly.

Memoization ?

Additional Hint :

Function calls are only valid if endIndex1 - startIndex1 = endIndex2 - startIndex2.
Can you just look at (startIndex1, endIndex1, startIndex2) and infer the endIndex2 based on these values ?
Or keep passing around (startIndex1, startIndex2, length) ?
Function calls are only valid if `endIndex1 - startIndex1 = endIndex2 - startIndex2`.
Can you just look at `(startIndex1, endIndex1, startIndex2)` and infer the `endIndex2` based on these values ?
Or keep passing around `(startIndex1, startIndex2, length)` ?


## Solution
Expand Down
37 changes: 24 additions & 13 deletions programming/strings/stringoholics.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,35 +22,46 @@ Eg: String is "abaa"
5. At time 5, string is "aaba", as 1 letters of the string "aaab" is circularly rotated to the back
```

After some units of time, a string becomes equal to it"s original self.
Once a string becomes equal to itself, it"s letters start to rotate from the first letter again (process resets). So, if a string takes t time to get back to the original, at time t+1 one letter will be rotated and the string will be it"s original self at 2t time.
You have to find the minimum time, where maximum number of strings are equal to their original self.
As this time can be very large, give the answer modulo 109+7.
After some units of time, a string becomes equal to its original self.

Note: Your solution will run on multiple test cases so do clear global variables after using them.
Once a string becomes equal to itself, its letters start to rotate from the first letter again (process resets).

Input:
So, if a string takes `t` time to get back to the original, at time t+1 one letter
will be rotated and the string will be its original self at `2t` time.

A: Array of strings.
Output:
You have to find the minimum time, where maximum number of strings are equal to their original self.

Minimum time, where maximum number of strings are equal to their original self.
Constraints:
As this time can be very large, give the answer modulo `10^9+7`.

Note: Your solution will run on multiple test cases so do clear global variables after using them.

### Input
```
A: Array of strings.
```
### Output
```
Minimum time, where maximum number of strings are equal to their original self.
```
### Constraints
```
1 <= size(A) <= 10^5
1 <= size of each string in A <= 10^5
Each string consists of only characters 'a' and 'b'
Summation of length of all strings <= 10^7
Example:
```

### Example

```
Input
A: [a,ababa,aba]
Output
4
```
String 'a' is it's original self at time 1, 2, 3 and 4.
String 'ababa' is it's original self only at time 4. (ababa => babaa => baaba => babaa => ababa)
String 'aba' is it's original self at time 2 and 4. (aba => baa => aba)
Expand All @@ -69,7 +80,7 @@ String 1010 takes 3 operations, while string 1001 takes 7 operations.

## Solution Approach

With respect to a single string, the total number of bits rotated after N operations is 1+2+3+.+N which is (N*(N+1))/2.
With respect to a single string, the total number of bits rotated after N operations is 1+2+3+....+N which is (N*(N+1))/2.
We get back the original string only when the total number of rotated bits is a multiple of the length of the string S(LEN).

This can be done in O(N) time for each string (Summation of length of all strings is <= 1e6), by finding all (N(N+1))/2 where N starts from 1 and goes upto (2LEN-1).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ Think how you can find the roman number of any integer using only fixed set of r

## Solution Approach

Create a hashmap/array with roman numerals of numbers 1, 2, 3, , 9, 10, 20, 30, , 90, 100, 200, , 1000, 2000, 3000, 4000.
Create a hashmap/array with roman numerals of numbers 1, 2, 3, ..., 9, 10, 20, 30, ..., 90, 100, 200, ..., 1000, 2000, 3000, 4000.

For any given number, find out its one’s, ten’s, hundred’s and thousand’s place and generate the roman number using the generated hash.

Expand Down

0 comments on commit 5554065

Please sign in to comment.