Backtracking

Standard backtracking

T: O(2 ^ n) For every index i two recursive case originates, So Time Complexity is O(2^n). There are 2 ^ n subsets to generate.

S: O(n) The space complexity can be reduced if the output array is not stored and the static and global variable is used to store the output string.

    public List<List<Integer>> subsets(int[] nums) {
        List<List<Integer>> result = new ArrayList<>();
        if (nums == null || nums.length == 0) return result;
        dfs(nums, 0, new ArrayList<>(), result);
        return result;
    }
    
    private void dfs(int[] nums, int startIndex, List<Integer> curt, List<List<Integer>> result) {
        result.add(new ArrayList<>(curt));
        for (int i = startIndex; i < nums.length; i++) {
            curt.add(nums[i]);
            dfs(nums, i + 1, curt, result);
            curt.remove(curt.size() - 1);
        }
    }

Sort array and add code below to skip over duplicates:

Typical backtracking template.

Remove duplicate by checking the last element is the same as current element. For example. [1, 1, 5, 6] only output one result [1, 5, 6]. Use if (i > startIndex && candidates[i] == candidates[i - 1]) continue; to remove duplicate.

To get the number of combinations sums to target. DFS Reduce each number on each level, if the target reach 0, it means there is 1 combination. Summarize the combinations of each level and return. Use memo to store sum : count relationship.

Backtracking starting from 0 on each level. Use a boolean array to check if this element has been visited.

Sort array. Also remove duplicate when the current element equals previous element, and the previous element is visited ().

T: O(2^n) proofarrow-up-right

The array is not sorted. For example, [4, 6, 7, 5, 7], you don't add

[4,6]

[4,6,7]

and [4,6,7]

but need add [4, 6, 7, 7]. It requires to remove duplicate on each layer by use a set.

End the traversal when reach leaf node. Add root.left != null and root.right != null condition to traversal to guarantee no null node is reached.

DFS Backtracking all path.

T: O(2 ^ n)

Add memorization. O(n * S)

Backtracking to generate parentheses as well as maintain balances of the brackets. Append "(" and left + 1, bal + 1, or append ")" and right + 1, bal - 1.

When bal < 0 it means any invalid solution such as "))((". When bal == 0 and sb.length() == n * 2 it means it is a valid solution.

T: O(2 ^ n) (actually it is 4^n / sqrt(n)) S: 4^n / sqrt(n)

Count the number of left brackets and right brackets when need to make a balance. Backtracking to get the string when left == 0 and right == 0 and balance == 0.

Description

T: O(3^n + 4^ m) where N is the number of digits in the input that maps to 3 letters (e.g. 2, 3, 4, 5, 6, 8) and M is the number of digits in the input that maps to 4 letters (e.g. 7, 9), and N+M is the total number digits in the input. S: T: O(3^n + 4^ m)

Backtracking until find answer. Be careful with the number of groups found.

Create a map to calculate all balance of each person. Store all non-zero balance to a list to do backtracking.

Start the backtracking from 0 position, set the list.get(pos) as curt value, find the next balance between pos + 1 and array length, check if next and curt are opposite sign (curt * next < 0).

Set the list(i) as curt + next then keep the traversal from pos + 1.

When see list.get(pos) == 0, means it can traverse from pos + 1.

Start from row 0, only fill col and cross diag on each spot. When row reach n, output a valid result. The cross diagonal coordinates are calculated by:

  • int cross1 = row + j;

  • int cross2 = row - j + n - 1;

Traverse the entire floor and detect if it is visited and movable. The direction is base on the sum of previous direction and the delta. turnRight to the next direction and ndir = (dir + k) % 4 . Also step back after the current dfs is completed.

Cut the pattern and str, backtracking to detect if any pattern would move forward. Use a set to detect the cut has been visited.

Use a StringBuilder to append the digits to crack the safe, also use visited set to keep track of all combinations. Add unique combinations as well as reach the passcode size equals to k^n.

This question asks to get all number of patterns from number of keys from m to n. Backtracking to sum up all numbers from starting point 1 to 9, also the remain combinations are between m to n.

Create a skip matrix to determine if the number need to be skipped. For example, between 1 to 3 is 2, it needs skip or visited. Use a boolean array to determine if a number is visited.

There is a way to eliminate the path. The combination starting from 1 is the same as starting from 3,7,9, also starting from 2 is the same as starting from 4,6,8. Which gives:

1240. Tiling a Rectangle with the Fewest Squares

  1. Go through every point in the rectangle, starting from (0,0), (0,1), ..., (n, m).

  2. If rect[r,..., r+k][c, ..., c+k] is an available area, then cover a k*k square starting at point (r,c).

  3. Try every possible size of square k * k, where k = min(n-r, m-c).

  4. Optimzation: If cnt >= ans, then stop.

2101. Detonate the Maximum Bombsarrow-up-right

1239. Maximum Length of a Concatenated String with Unique Charactersarrow-up-right

Last updated

Was this helpful?