View on GitHub

SCRATCH PAD

No polish, just pulse

Striver’s SDE Sheet Notes (Day 9: Recursion)


1. Subset Sums

  public List<Integer> subsetSums(int[] nums) {
      List<Integer> result = new ArrayList<>();
      backtrack(nums, 0, 0, result);
      return result;
  }

  private void backtrack(int[] nums, int index, int currentSum, List<Integer> result) {
      if (index == nums.length) {
          result.add(currentSum);
          return;
      }
      backtrack(nums, index + 1, currentSum + nums[index], result);  // Include current number
      backtrack(nums, index + 1, currentSum, result);  // Exclude current number
  }
  

2. Subset-II

  public List<List<Integer>> subsetsWithDup(int[] nums) {
      List<List<Integer>> result = new ArrayList<>();
      Arrays.sort(nums);
      backtrack(nums, 0, new ArrayList<>(), result);
      return result;
  }

  private void backtrack(int[] nums, int start, List<Integer> current, List<List<Integer>> result) {
      result.add(new ArrayList<>(current));
      for (int i = start; i < nums.length; i++) {
          if (i > start && nums[i] == nums[i - 1]) continue;  // Skip duplicates
          current.add(nums[i]);
          backtrack(nums, i + 1, current, result);
          current.remove(current.size() - 1);
      }
  }
  

3. Combination Sum-1

  public List<List<Integer>> combinationSum(int[] candidates, int target) {
      List<List<Integer>> result = new ArrayList<>();
      backtrack(candidates, 0, target, new ArrayList<>(), result);
      return result;
  }

  private void backtrack(int[] candidates, int start, int target, List<Integer> current, List<List<Integer>> result) {
      if (target == 0) {
          result.add(new ArrayList<>(current));
          return;
      }
      for (int i = start; i < candidates.length; i++) {
          if (candidates[i] > target) continue;
          current.add(candidates[i]);
          backtrack(candidates, i, target - candidates[i], current, result);  // Can reuse the same number
          current.remove(current.size() - 1);
      }
  }
  

4. Combination Sum-2

  public List<List<Integer>> combinationSum2(int[] candidates, int target) {
      List<List<Integer>> result = new ArrayList<>();
      Arrays.sort(candidates);
      backtrack(candidates, 0, target, new ArrayList<>(), result);
      return result;
  }

  private void backtrack(int[] candidates, int start, int target, List<Integer> current, List<List<Integer>> result) {
      if (target == 0) {
          result.add(new ArrayList<>(current));
          return;
      }
      for (int i = start; i < candidates.length; i++) {
          if (i > start && candidates[i] == candidates[i - 1]) continue;  // Skip duplicates
          if (candidates[i] > target) break;
          current.add(candidates[i]);
          backtrack(candidates, i + 1, target - candidates[i], current, result);
          current.remove(current.size() - 1);
      }
  }
  

5. Palindrome Partitioning

  public List<List<String>> partition(String s) {
      List<List<String>> result = new ArrayList<>();
      backtrack(s, 0, new ArrayList<>(), result);
      return result;
  }

  private void backtrack(String s, int start, List<String> current, List<List<String>> result) {
      if (start == s.length()) {
          result.add(new ArrayList<>(current));
          return;
      }
      for (int end = start + 1; end <= s.length(); end++) {
          String substring = s.substring(start, end);
          if (isPalindrome(substring)) {
              current.add(substring);
              backtrack(s, end, current, result);
              current.remove(current.size() - 1);
          }
      }
  }

  private boolean isPalindrome(String s) {
      int left = 0, right = s.length() - 1;
      while (left < right) {
          if (s.charAt(left) != s.charAt(right)) return false;
          left++;
          right--;
      }
      return true;
  }
  

6. K-th Permutation Sequence

  public String getPermutation(int n, int k) {
      List<Integer> numbers = new ArrayList<>();
      for (int i = 1; i <= n; i++) numbers.add(i);
      int fact = 1;
      for (int i = 1; i < n; i++) fact *= i;
      k--;  // Convert k to zero-based index
      StringBuilder result = new StringBuilder();
      for (int i = n - 1; i >= 0; i--) {
          int index = k / fact;
          result.append(numbers.get(index));
          numbers.remove(index);
          if (i > 0) k %= fact;
          fact /= i;
      }
      return result.toString();
  }