From 4547e60b71f441a05c63d8eef6bf5564373b3847 Mon Sep 17 00:00:00 2001 From: Hardik Prajapati Date: Fri, 26 Sep 2025 16:02:54 -0700 Subject: [PATCH] Backtracking2:All done --- palindrome partitioning.py | 46 +++++++++++++++++++++++++++++++++++ subsets.py | 50 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 palindrome partitioning.py create mode 100644 subsets.py diff --git a/palindrome partitioning.py b/palindrome partitioning.py new file mode 100644 index 00000000..ee2978df --- /dev/null +++ b/palindrome partitioning.py @@ -0,0 +1,46 @@ +''' +Solution : FOR loop based DFS with backtracking + - At each character in the string, we either partition at that character or not + - If this partitioned string is valid palindrome than we recurse to the next step + which is partitioning the rest of the string. + - If we end up reaching end of string in the recursive call, then we have a valid + palindrome partitioning. +Time Complexity: O(N*2^N), where N = length of string. + - At each character, we have choose/Not choose to partition. + - for partitioned, we do palindrome check. +Space Complexity: O(N), depth of recursive stack. +''' + +class Solution: + def partition(self, s: str) -> List[List[str]]: + validPalindromePartitions = [] # to store the answers + + self.helper(s,0,[],validPalindromePartitions) # string, pivot, path, answer_list + + return validPalindromePartitions + + def helper(self,s,pivot_index,path,validPalindromePartitions): + # base + if pivot_index==len(s): # new valid partitioned path found + validPalindromePartitions.append(deepcopy(path)) + return + + # logic + for i in range(pivot_index,len(s)): + partitioned_string = s[pivot_index:i+1] # partition string + if self.isPalindrome(partitioned_string): # check if pallindrome + path.append(partitioned_string) # action + self.helper(s,i+1,path,validPalindromePartitions) + path.pop() # backtrack + + def isPalindrome(self,string): + left = 0 + right = len(string)-1 + + while left List[List[int]]: + subsets_list = [] + self.helper(nums,0,[],subsets_list) #nums, current_index, current path, answer list + + return subsets_list + + def helper(self, nums, current_index, current_path, subsets_list): + # base + if current_index==len(nums): # captured the new subset + subsets_list.append(deepcopy(current_path)) + return + + # logic + # no choose + self.helper(nums, current_index+1, current_path, subsets_list) + + # choose + current_path.append(nums[current_index]) # action + self.helper(nums, current_index+1, current_path, subsets_list) + current_path.pop() # backtrack + +''' +Solution 2: For loop based recursion with backtracking +Time Complexity: O(2^N), N =len(nums) +Space Complexity: O(N), recursive stack, height of tree. +''' +class Solution: + def subsets(self, nums: List[int]) -> List[List[int]]: + subsets_list = [] + self.helper(nums,0,[],subsets_list) #nums, pivot index, current path, answer list + + return subsets_list + + def helper(self, nums, pivot_index, current_path, subsets_list): + # base - not needed + + + + # logic + subsets_list.append(deepcopy(current_path)) + for i in range(pivot_index,len(nums)): + current_path.append(nums[i]) # action + self.helper(nums, i+1, current_path, subsets_list) + current_path.pop() # backtrack