Showing posts with label Parentheses. Show all posts
Showing posts with label Parentheses. Show all posts

LeetCode 761 - Special Binary String


https://www.cnblogs.com/grandyang/p/8606024.html
Special binary strings are binary strings with the following two properties:

  • The number of 0's is equal to the number of 1's.
  • Every prefix of the binary string has at least as many 1's as 0's.

Given a special string S, a move consists of choosing two consecutive, non-empty, special substrings of S, and swapping them. (Two strings are consecutive if the last character of the first string is exactly one index before the first character of the second string.)
At the end of any number of moves, what is the lexicographically largest resulting string possible?
Example 1:
Input: S = "11011000"
Output: "11100100"
Explanation:
The strings "10" [occuring at S[1]] and "1100" [at S[3]] are swapped.
This is the lexicographically largest string possible after some number of swaps.

Note:
  1. S has length at most 50.
  2. S is guaranteed to be a special binary string as defined above.

https://leetcode.com/problems/special-binary-string/discuss/113211/JavaC%2B%2BPython-Easy-and-Concise-Recursion
Just 4 steps:
  1. Split S into several special strings (as many as possible).
  2. Special string starts with 1 and ends with 0. Recursion on the middle part.
  3. Sort all special strings in lexicographically largest order.
  4. Join and output all strings.

Update

The middle part of a special string may not be another special string. But in my recursion it is.
For example, 1M0 is a splitted special string. M is its middle part and it must be another special string.
Because:
  1. The number of 0's is equal to the number of 1's in M
  2. If there is a prefix P of Mwhich has one less 1's than 0's, 1P will make up a special string. 1P will be found as special string before 1M0 in my solution.
    It means that every prefix of M has at least as many 1's as 0's.
Based on 2 points above, M is a special string.


public String makeLargestSpecial(String S) {
        int count = 0, i = 0;
        List<String> res = new ArrayList<String>();
        for (int j = 0; j < S.length(); ++j) {
          if (S.charAt(j) == '1') count++;
          else count--;
          if (count == 0) {
            res.add('1' + makeLargestSpecial(S.substring(i + 1, j)) + '0');
            i = j + 1;
          }
        }
        Collections.sort(res, Collections.reverseOrder());
        return String.join("", res);
    }
https://leetcode.com/problems/special-binary-string/discuss/155621/Logical-Thinking-with-Clear-Code
Logical Thinking
If we regard 1, 0 in the definition of the special string as '(' and ')' separately,
the problem is actually to get the string which is so-called valid parenthesis and meanwhile is the lexicographically largest.
It is intuitive that we prefer deeper valid parenthesis to sit in front (deeper means the string surrounded with more pairs of parenthesis, e.g., '(())' is deeper than '()' ). We can achieve that by sorting them reversely.
we go through S. Whenever the parentheses we met can be balanced (i.e., balance == 0), we construct valid parentheses -- by putting (on the left boundary, )on the right boundary, and doing with the inner part following the same pattern.
Clear Java Code


    public String makeLargestSpecial(String S) {
        
        int balance = 0, l = 0;
        List<String> subResults = new LinkedList<>();
        for (int r = 0; r < S.length(); r++) {
            if (S.charAt(r) == '0') {
                balance--;
            }
            else {
                balance++;
            }
            if (balance == 0) {
                subResults.add("1" + makeLargestSpecial(S.substring(l + 1, r)) + "0");
                l = r + 1;
            }
        }
        Collections.sort(subResults, Collections.reverseOrder());
        
        return String.join("", subResults);
    }
https://leetcode.com/problems/special-binary-string/discuss/113212/Think-of-it-as-Valid-Parentheses
According to the description , there are 2 requirement for Special-String
  1. The number of 0's is equal to the number of 1's.
  2. Every prefix of the binary string has at least as many 1's as 0's.
The 2nd definition is essentially saying that at any point of the string, you cannot have more 0's than 1's.
If we map '1' to '(''0's to ')', a Special-String is essentially Valid-Parentheses, therefore share all the properties of a Valid-Parentheses
VP (Valid-Parentheses) have 2 form:
  1. single nested VP like "(())", or "1100";
  2. a number of consecutive sub-VPs like "()(())", or "101100", which contains "()" + "(())" or "10" + "1100"
And this problem is essentially ask you to reorder the sub-VPs in a VP to make it bigger. If we look at this example : "()(())" or "101100", how would you make it bigger?
Answer is, by moving the 2nd sub-string to the front. Because deeply nested VP contains more consecutive '('s or '1's in the front. That will make reordered string bigger.
The above example is straitforward, and no recursion is needed. But, what if the groups of sub-VPs are not in the root level?
Like if we put another "()(())" inside "()(())", like "()(( ()(()) ))", in this case we will need to recursively reorder the children, make them MVP(Max-Valid-Parentheses), then reorder in root.
To summarize, we just need to reorder all groups of VPs or SS's at each level to make them MVP, then reorder higher level VPs;
    string makeLargestSpecial(string s) {
        int i = 0;
        return dfs(s, i);
    }

private:
    string dfs(string& s, int& i) {
        string res;
        vector<string> toks;
        while (i < s.size() && res.empty()) {
            if (s[i++] == '1') toks.push_back(dfs(s, i));
            else res += "1";
        }
        bool prefix = res.size();
        sort(toks.begin(), toks.end());
        for (auto it = toks.rbegin(); it != toks.rend(); it++) res += *it;
        if (prefix) res += '0';
        return res;
    }


这道题给了我们一个特殊的二进制字符串,说是需要满足两个要求,一是0和1的个数要相等,二是任何一个前缀中的1的个数都要大于等于0的个数。根据压力山大大神的帖子,其实就是一个括号字符串啊。这里的1表示左括号,0表示右括号,那么题目中的两个限制条件其实就是限定这个括号字符串必须合法,即左右括号的个数必须相同,且左括号的个数随时都要大于等于右括号的个数,可以参见类似的题目Valid Parenthesis String。那么这道题让我们通过交换子字符串,生成字母顺序最大的特殊字符串,注意这里交换的子字符串也必须是特殊字符串,满足题目中给定的两个条件,换作括号来说就是交换的子括号字符串也必须是合法的。那么我们来想什么样的字符串是字母顺序最大的呢,根据题目中的例子可以分析得出,应该是1靠前的越多越好,那么换作括号来说就是括号嵌套多的应该放在前面。比如我们分析题目中的例子:
11011000    ->    (()(()))
11100100    ->    ((())())
我们发现,题目中的例子中的交换操作其实是将上面的红色部分和蓝色部分交换了,因为蓝色的部分嵌套的括号多,那么左括号就多,在前面的1就多,所以字母顺序大。所以我们要做的就是将中间的子串分别提取出来,然后排序,再放回即可。上面的这个例子相对简单一些,实际上上面的红色和蓝色部分完全可以更复杂,所以再给它们排序之前,其自身的顺序应该已经按字母顺序排好了才行,这种特点天然适合递归的思路,先递归到最里层,然后一层一层向外扩展,直至完成所有的排序。
好,下面我们来看递归函数的具体写法,由于我们移动的子字符串也必须是合法的,那么我们利用检测括号字符串合法性的一个最常用的方法,就是遇到左括号加1,遇到右括号-1,这样得到0的时候,就是一个合法的子字符串了。我们用变量i来统计这个合法子字符串的起始位置,字符串数组v来保存这些合法的子字符串。好了,我们开始遍历字符串S,遇到1,cnt自增1,否则自减1。当cnt为0时,我们将这个字串加入v,注意前面说过,我们需要给这个字串自身也排序,所以我们要对自身调用递归函数,我们不用对整个子串调用递归,因为字串的起始位置和结束位置是确定的,一定是1和0,我们只需对中间的调用递归即可,然后更新i为j+1。当我们将所有排序后的合法字串存入v中后,我们对v进行排序,将字母顺序大的放前面,最后将其连为一个字符串即可


LeetCode 20 - Valid Parentheses


https://leetcode.com/problems/valid-parentheses/
Given a string containing just the characters '('')''{''}''[' and ']', determine if the input string is valid.
An input string is valid if:
  1. Open brackets must be closed by the same type of brackets.
  2. Open brackets must be closed in the correct order.
Note that an empty string is also considered valid.
Example 1:
Input: "()"
Output: true
Example 2:
Input: "()[]{}"
Output: true
        Deque<Character> stack = new LinkedList<>();
        for(int i = 0;i< s.length() ;i++){
            if(s.charAt(i) == ')'){
                if(stack.isEmpty() || (stack.pop() != '(')) return false;
            }else if(s.charAt(i) == ']'){
                if(stack.isEmpty() || (stack.pop() != '[')) return false;
            }else if(s.charAt(i) == '}'){
                if(stack.isEmpty() || (stack.pop() != '{')) return false;
            }else stack.push(s.charAt(i));
        }
        return stack.isEmpty();
    }

public boolean isValid(String s) {
 Stack<Character> stack = new Stack<Character>();
 for (char c : s.toCharArray()) {
  if (c == '(')
   stack.push(')');
  else if (c == '{')
   stack.push('}');
  else if (c == '[')
   stack.push(']');
  else if (stack.isEmpty() || stack.pop() != c)
   return false;
 }
 return stack.isEmpty();
}

  // Hash table that takes care of the mappings.
  private HashMap<Character, Character> mappings;

  // Initialize hash map with mappings. This simply makes the code easier to read.
  public Solution() {
    this.mappings = new HashMap<Character, Character>();
    this.mappings.put(')', '(');
    this.mappings.put('}', '{');
    this.mappings.put(']', '[');
  }

  public boolean isValid(String s) {

    // Initialize a stack to be used in the algorithm.
    Stack<Character> stack = new Stack<Character>();

    for (int i = 0; i < s.length(); i++) {
      char c = s.charAt(i);

      // If the current character is a closing bracket.
      if (this.mappings.containsKey(c)) {

        // Get the top element of the stack. If the stack is empty, set a dummy value of
        // '#'
        char topElement = stack.empty() ? '#' : stack.pop();

        // If the mapping for this bracket doesn't match the stack's top element, return
        // false.
        if (topElement != this.mappings.get(c)) {
          return false;
        }
      } else {
        // If it was an opening bracket, push to the stack.
        stack.push(c);
      }
    }

    // If the stack still contains elements, then it is an invalid expression.
    return stack.isEmpty();
  }



LeetCode 921 - Minimum Add to Make Parentheses Valid


Related: Minimum number of bracket reversals needed to make an expression balanced
https://leetcode.com/problems/minimum-add-to-make-parentheses-valid/
Given a string S of '(' and ')' parentheses, we add the minimum number of parentheses ( '(' or ')', and in any positions ) so that the resulting parentheses string is valid.
Formally, a parentheses string is valid if and only if:
  • It is the empty string, or
  • It can be written as AB (A concatenated with B), where A and B are valid strings, or
  • It can be written as (A), where A is a valid string.
Given a parentheses string, return the minimum number of parentheses we must add to make the resulting string valid.

Keep track of the balance of the string: the number of '(''s minus the number of ')''s. A string is valid if its balance is 0, plus every prefix has non-negative balance.
The above idea is common with matching brackets problems, but could be difficult to find if you haven't seen it before.
Now, consider the balance of every prefix of S. If it is ever negative (say, -1), we must add a '(' bracket. Also, if the balance of S is positive (say, +B), we must add B ')' brackets at the end.

  public int minAddToMakeValid(String S) {
    int ans = 0, bal = 0;
    for (int i = 0; i < S.length(); ++i) {
      bal += S.charAt(i) == '(' ? 1 : -1;
      // It is guaranteed bal >= -1
      if (bal == -1) {
        ans++;
        bal++;
      }
    }

    return ans + bal;
  }
https://leetcode.com/problems/minimum-add-to-make-parentheses-valid/discuss/181132/C%2B%2BJavaPython-Straight-Forward-One-Pass

To make a string valid,
we can add some ( on the left,
and add some ) on the right.
We need to find the number of each.
Explanation:
left records the number of ( we need to add.
right records the current opened parentheses.
Loop char i on the string:
If right == 0 && i == ')',
it means no left parentheses can mathch this right parentheses,
we have to add one more left parentheses on the left of the string.
Otherwise, we update right.
Return left + right in the end


    public int minAddToMakeValid(String S) {
        int left = 0, right = 0;
        for (char i : S.toCharArray()) {
            if (right == 0 && i == ')')
                left++;
            else
                right += i == '(' ? 1 : -1;
        }
        return left + right;
    }
X. https://leetcode.com/problems/minimum-add-to-make-parentheses-valid/discuss/181086/Java-two-one-pass-7-liners-space-O(n)-and-O(1)-respectively
Loop through the input array.


  1. if encounter '(', push '(' into stack;
  2. otherwise, ')', check if there is a matching '(' on top of stack; if no, increase the counter by 1; if yes, pop it out;
  3. after the loop, count in the un-matched characters remaining in the stack.


Time & space: O(n).
    public int minAddToMakeValid(String S) {
        Deque<Character> stk = new ArrayDeque<>();
        int count = 0;
        for (char c : S.toCharArray()) {
            if (c == '(') { stk.push(c); }
            else if (stk.isEmpty()) { ++count; }
            else { stk.pop(); }
        }
        return count + stk.size();
    }
Method 2:
Since there is only one kind of char, '(', in stack,only a counter will also work.
Time: O(n), space: O(1).
    public int minAddToMakeValid(String S) {
        int count = 0, stk = 0;
        for (int i = 0; i < S.length(); ++i) {
            if (S.charAt(i) == '(') { ++stk; }
            else if (stk <= 0) { ++count; }
            else { --stk; }
        }
        return count + stk;
    }
X. https://leetcode.com/problems/minimum-add-to-make-parentheses-valid/discuss/181092/Java-Solution-From-Two-Pass-to-One-Pass1
    public int minAddToMakeValid(String S) {
        if (S == null || S.length() == 0) {
            return 0;
        }
        
        int open = 0;
        int res = 0;
        
        for (char c : S.toCharArray()) {
            if (c == '(') {
                open++;
            } else {
                open--;
                if (open < 0) {
                    res++;
                    open++;
                }
            }
        }
        
        int close = 0;
        for (int i = S.length() - 1; i >= 0; i--) {
            char c = S.charAt(i);
            if (c == ')'){
                close++;
            } else {
                close--;
                if (close < 0) {
                    res++;
                    close++;
                }
            }
        }
        
        return res;
    }
http://www.noteanddata.com/leetcode-921-Minimum-Add-to-Make-Parentheses-Valid-solution-note.html
首先想到的是能不能直接遍历一下字符串,然后返回Math.abs(leftcount-rightcount),
但是看到"))(("这样的case显然不能通过,所以在遍历的过程中,如果右括号不能被匹配,那么就直接需要计数了。
也就是常规的用stack的思路,如果遇到左括号就push,遇到右括号就pop。 但是如果遇到右括号的时候stack是空的,那就要计数了。
还有最后剩下的左括号个数也需要加上。
由于这里只需要返回个数,所以不需要用stack,直接用两个count就好。
public int minAddToMakeValid(String S) {
    int leftcount = 0, missingleft = 0;
    
    for(int i = 0; i < S.length(); ++i) {
        if('(' == S.charAt(i)) {
            leftcount++;
        }
        else {
            leftcount--;
            if(leftcount < 0) {
                missingleft++;
                leftcount = 0;
            }
        }
    }
    return leftcount + missingleft;
}



Labels

LeetCode (1432) GeeksforGeeks (1122) LeetCode - Review (1067) Review (882) Algorithm (668) to-do (609) Classic Algorithm (270) Google Interview (237) Classic Interview (222) Dynamic Programming (220) DP (186) Bit Algorithms (145) POJ (141) Math (137) Tree (132) LeetCode - Phone (129) EPI (122) Cracking Coding Interview (119) DFS (115) Difficult Algorithm (115) Lintcode (115) Different Solutions (110) Smart Algorithm (104) Binary Search (96) BFS (91) HackerRank (90) Binary Tree (86) Hard (79) Two Pointers (78) Stack (76) Company-Facebook (75) BST (72) Graph Algorithm (72) Time Complexity (69) Greedy Algorithm (68) Interval (63) Company - Google (62) Geometry Algorithm (61) Interview Corner (61) LeetCode - Extended (61) Union-Find (60) Trie (58) Advanced Data Structure (56) List (56) Priority Queue (53) Codility (52) ComProGuide (50) LeetCode Hard (50) Matrix (50) Bisection (48) Segment Tree (48) Sliding Window (48) USACO (46) Space Optimization (45) Company-Airbnb (41) Greedy (41) Mathematical Algorithm (41) Tree - Post-Order (41) ACM-ICPC (40) Algorithm Interview (40) Data Structure Design (40) Graph (40) Backtracking (39) Data Structure (39) Jobdu (39) Random (39) Codeforces (38) Knapsack (38) LeetCode - DP (38) Recursive Algorithm (38) String Algorithm (38) TopCoder (38) Sort (37) Introduction to Algorithms (36) Pre-Sort (36) Beauty of Programming (35) Must Known (34) Binary Search Tree (33) Follow Up (33) prismoskills (33) Palindrome (32) Permutation (31) Array (30) Google Code Jam (30) HDU (30) Array O(N) (29) Logic Thinking (29) Monotonic Stack (29) Puzzles (29) Code - Detail (27) Company-Zenefits (27) Microsoft 100 - July (27) Queue (27) Binary Indexed Trees (26) TreeMap (26) to-do-must (26) 1point3acres (25) GeeksQuiz (25) Merge Sort (25) Reverse Thinking (25) hihocoder (25) Company - LinkedIn (24) Hash (24) High Frequency (24) Summary (24) Divide and Conquer (23) Proof (23) Game Theory (22) Topological Sort (22) Lintcode - Review (21) Tree - Modification (21) Algorithm Game (20) CareerCup (20) Company - Twitter (20) DFS + Review (20) DP - Relation (20) Brain Teaser (19) DP - Tree (19) Left and Right Array (19) O(N) (19) Sweep Line (19) UVA (19) DP - Bit Masking (18) LeetCode - Thinking (18) KMP (17) LeetCode - TODO (17) Probabilities (17) Simulation (17) String Search (17) Codercareer (16) Company-Uber (16) Iterator (16) Number (16) O(1) Space (16) Shortest Path (16) itint5 (16) DFS+Cache (15) Dijkstra (15) Euclidean GCD (15) Heap (15) LeetCode - Hard (15) Majority (15) Number Theory (15) Rolling Hash (15) Tree Traversal (15) Brute Force (14) Bucket Sort (14) DP - Knapsack (14) DP - Probability (14) Difficult (14) Fast Power Algorithm (14) Pattern (14) Prefix Sum (14) TreeSet (14) Algorithm Videos (13) Amazon Interview (13) Basic Algorithm (13) Codechef (13) Combination (13) Computational Geometry (13) DP - Digit (13) LCA (13) LeetCode - DFS (13) Linked List (13) Long Increasing Sequence(LIS) (13) Math-Divisible (13) Reservoir Sampling (13) mitbbs (13) Algorithm - How To (12) Company - Microsoft (12) DP - Interval (12) DP - Multiple Relation (12) DP - Relation Optimization (12) LeetCode - Classic (12) Level Order Traversal (12) Prime (12) Pruning (12) Reconstruct Tree (12) Thinking (12) X Sum (12) AOJ (11) Bit Mask (11) Company-Snapchat (11) DP - Space Optimization (11) Dequeue (11) Graph DFS (11) MinMax (11) Miscs (11) Princeton (11) Quick Sort (11) Stack - Tree (11) 尺取法 (11) 挑战程序设计竞赛 (11) Coin Change (10) DFS+Backtracking (10) Facebook Hacker Cup (10) Fast Slow Pointers (10) HackerRank Easy (10) Interval Tree (10) Limited Range (10) Matrix - Traverse (10) Monotone Queue (10) SPOJ (10) Starting Point (10) States (10) Stock (10) Theory (10) Tutorialhorizon (10) Kadane - Extended (9) Mathblog (9) Max-Min Flow (9) Maze (9) Median (9) O(32N) (9) Quick Select (9) Stack Overflow (9) System Design (9) Tree - Conversion (9) Use XOR (9) Book Notes (8) Company-Amazon (8) DFS+BFS (8) DP - States (8) Expression (8) Longest Common Subsequence(LCS) (8) One Pass (8) Quadtrees (8) Traversal Once (8) Trie - Suffix (8) 穷竭搜索 (8) Algorithm Problem List (7) All Sub (7) Catalan Number (7) Cycle (7) DP - Cases (7) Facebook Interview (7) Fibonacci Numbers (7) Flood fill (7) Game Nim (7) Graph BFS (7) HackerRank Difficult (7) Hackerearth (7) Inversion (7) Kadane’s Algorithm (7) Manacher (7) Morris Traversal (7) Multiple Data Structures (7) Normalized Key (7) O(XN) (7) Radix Sort (7) Recursion (7) Sampling (7) Suffix Array (7) Tech-Queries (7) Tree - Serialization (7) Tree DP (7) Trie - Bit (7) 蓝桥杯 (7) Algorithm - Brain Teaser (6) BFS - Priority Queue (6) BFS - Unusual (6) Classic Data Structure Impl (6) DP - 2D (6) DP - Monotone Queue (6) DP - Unusual (6) DP-Space Optimization (6) Dutch Flag (6) How To (6) Interviewstreet (6) Knapsack - MultiplePack (6) Local MinMax (6) MST (6) Minimum Spanning Tree (6) Number - Reach (6) Parentheses (6) Pre-Sum (6) Probability (6) Programming Pearls (6) Rabin-Karp (6) Reverse (6) Scan from right (6) Schedule (6) Stream (6) Subset Sum (6) TSP (6) Xpost (6) n00tc0d3r (6) reddit (6) AI (5) Abbreviation (5) Anagram (5) Art Of Programming-July (5) Assumption (5) Bellman Ford (5) Big Data (5) Code - Solid (5) Code Kata (5) Codility-lessons (5) Coding (5) Company - WMware (5) Convex Hull (5) Crazyforcode (5) DFS - Multiple (5) DFS+DP (5) DP - Multi-Dimension (5) DP-Multiple Relation (5) Eulerian Cycle (5) Graph - Unusual (5) Graph Cycle (5) Hash Strategy (5) Immutability (5) Java (5) LogN (5) Manhattan Distance (5) Matrix Chain Multiplication (5) N Queens (5) Pre-Sort: Index (5) Quick Partition (5) Quora (5) Randomized Algorithms (5) Resources (5) Robot (5) SPFA(Shortest Path Faster Algorithm) (5) Shuffle (5) Sieve of Eratosthenes (5) Strongly Connected Components (5) Subarray Sum (5) Sudoku (5) Suffix Tree (5) Swap (5) Threaded (5) Tree - Creation (5) Warshall Floyd (5) Word Search (5) jiuzhang (5)

Popular Posts