Split sequences ending with 0 and 1 (Algorithm explained)
IntuitionSince its binary string, sub-sequence can only end with '1' or '0'. This can be used to build up our algorithm.  Instead of actual squences, we will us
# Intuition
Since its binary string, sub-sequence can only end with '1' or '0'. This can be used to build up our algorithm.  Instead of actual squences, we will use the infered counts for them. 

**Important observation:**
Each append of '1' or '0' to some sequence will create a new unique sequence. 

So we will count our sequences for given ith position by taking help from sequences for (i-1)th position.

Lets keep track of two counts, first the count of sequences which ends with 1 (endWith1). And second the count of sequences which ends with 0 (endWith0).

Iterating from left to right in binary string:
1. If we encounter '0' than we can append this 0 to all existing endWith0 and endWith1 sequences. Leading to new endWith0 => endWith0 + endWith1 (As appending 0 in end of different sequences gives different unique strings). We also check if atleast one "0" is encountered, since standalone "0" is valid sequence.
2. If we encounter '1' than we can append this 1 to all existing endWith0 and endWith1 sequences. Leading to new endWith1 => endWith0 + endWith1 + 1 (why this extra 1, read below). 

Technically we will always have only one "1" unique sequence and only one "0" unique sequence. But our above calculation logic is bit different for both. Why is that? 
Lets see it by example:

**Case 1**:
Lets say string was "111", not adding "1" to strings ending with 1 set, instead will increment total count by one in end.

First '1':
-----> endsWith1: [1]
Second '1':
-----> endsWith1: [11]
Third '1':
-----> endsWith1: [111]

See we have a loss here by the time we reach 3rd '1'. Total count in set is 1 and incrementing by one for sequence "1" equals to 2. 

But it should be like below:
 
First '1':
-----> endsWith1: [1]
Second '1':
-----> endsWith1: [11, 1]
Third '1':
-----> endsWith1: [111, 11, 1]

Total count => 3 (correct answer)

**Note** that "1" is ALWAYS carried forward in the set, not duplicated.

**Case 2**:
Binary string is "100", not adding "0" to strings ending with 0 set, instead will increment total count by one in end.

Pos 0: '1'
-----> endsWith1: [1], endsWith0: []
Pos 1: '0'
-----> endsWith1: [1], endsWith0: [10]
Pos 2: '0'
-----> endsWith1: [1], endsWith0: [100, 10] 

Note that "10" in endsWith0 in last iteration came from appending zero to endsWith1 entry of "1")

Total count in set is endsWith1 + endsWith0 counts => 3 and incrementing it by one more for sequence "0" equals to 4. Which is correct answer (1, 100, 10, 0). 

Now assume we had followed the approach of 0 appending same as 1 appending from above.

Pos 0: '1'
-----> endsWith1: [1], endsWith0: []
Pos 1: '0'
-----> endsWith1: [1], endsWith0: [10, 0]
Pos 2: '0'
-----> endsWith1: [1], endsWith0: [100, 10, 00, 0] 

Total count => endsWith1 + endsWith0 => 5 (WRONG)

See in last iteration we got invalid entry of "00". So we cant follow same approach for both the cases and reason why we separate out one "0" sequence compared to one "1" sequence. Hence why we split 1 ending and 0 ending sequences. Otherwise we could have directly doubled in each iteration (sed lyf!).

I hope above examples fills missing pieces from other solutions.

# Complexity
- Time complexity:
O(n)

- Space complexity:
O(1)

# Code
```java []
class Solution {
    public int numberOfUniqueGoodSubsequences(String binary) {
        int mod = (int) 1e9 + 7;
        int endsWithZero = 0;
        int endsWithOne = 0;
        int seenZero = 0;

        for(int i = 0; i < binary.length(); i++) {
            if(binary.charAt(i) == '0') {
                endsWithZero = (endsWithZero + endsWithOne) % mod;
                seenZero = 1;
            } else {
                endsWithOne = (endsWithZero + endsWithOne + 1) % mod;
            }
        }

        return (endsWithZero + endsWithOne + seenZero) % mod;
    }
}
```
['Java']