<h1> Backtracking </h1> <h2> - [O] 401. Binary Watch </h2> <h3> 題目 </h3> A binary watch has 4 LEDs on the top to represent the hours (0-11), and 6 LEDs on the bottom to represent the minutes (0-59). Each LED represents a zero or one, with the least significant bit on the right. For example, the below binary watch reads "4:51". ![](https://i.imgur.com/b0PqA1D.jpg) Given an integer turnedOn which represents the number of LEDs that are currently on (ignoring the PM), return all possible times the watch could represent. You may return the answer in any order. The hour must not contain a leading zero. For example, "01:00" is not valid. It should be "1:00". The minute must be consist of two digits and may contain a leading zero. For example, "10:2" is not valid. It should be "10:02". **Example1** ``` Input: turnedOn = 1 Output: ["0:01","0:02","0:04","0:08","0:16","0:32","1:00","2:00","4:00","8:00"] ``` <h3> 思路 </h3> 利用Backtracking慢慢找,把turnedOn的數字分成時和分,再慢慢做recurssion。 ```python! class Solution(object): def __init__(self): self.ans=[] def readBinaryWatch(self, turnedOn): hour=[1,2,4,8] minute=[1,2,4,8,16,32] if turnedOn==0: return ["0:00"] for i in xrange(0,5): if turnedOn<i: break self.combineTime(hour,minute,0,0,i,turnedOn-i) return self.ans def combineTime(self,hourTable,minuteTable,hour,minute,turnedOnhour,turnedOnminute): if hour>11 or minute>59: return if turnedOnhour==0 and turnedOnminute==0: if minute<10: if self.ans.count(str(hour)+":"+"0"+str(minute))>0: return self.ans.append(str(hour)+":"+"0"+str(minute)) else: if self.ans.count(str(hour)+":"+str(minute))>0: return self.ans.append(str(hour)+":"+str(minute)) else: for i in xrange(0,len(hourTable)): if turnedOnhour==0: break if hour>=hourTable[i]: continue hour+=hourTable[i] turnedOnhour-=1 self.combineTime(hourTable,minuteTable,hour,minute,turnedOnhour,turnedOnminute) turnedOnhour+=1 hour-=hourTable[i] for i in xrange(0,len(minuteTable)): if turnedOnminute==0: break if minute>=minuteTable[i]: continue minute+=minuteTable[i] turnedOnminute-=1 self.combineTime(hourTable,minuteTable,hour,minute,turnedOnhour,turnedOnminute) turnedOnminute+=1 minute-=minuteTable[i] """ :type turnedOn: int :rtype: List[str] """ ``` --- <h2> - [O]1980. Find Unique Binary String </h2> <h3> 題目 </h3> Given an array of strings nums containing n unique binary strings each of length n, return a binary string of length n that does not appear in nums. If there are multiple answers, you may return any of them. **Example 1** ``` Input: nums = ["01","10"] Output: "11" Explanation: "11" does not appear in nums. "00" would also be correct. ``` <h3> 思路 </h3> 利用Backtracking依序排列每種可能的Binary String,若發現題目沒有的就return。 ```python! class Solution(object): def makenumbers(self,table,size,target): if len(target)==size: if table.get(target)==None: return target else: return -1 zero=target+"0" one=target+"1" zeroResult=self.makenumbers(table,size,zero) oneResult=self.makenumbers(table,size,one) if zeroResult!=-1: return zeroResult else: return oneResult def findDifferentBinaryString(self, nums): table={} for i in xrange(0,len(nums)): table[nums[i]]=0 zero=self.makenumbers(table,len(nums[0]),"0") one= self.makenumbers(table,len(nums[0]),"1") if zero!=-1: return zero return one """ :type nums: List[str] :rtype: str """ ``` --- <h2> - [O]797. All Paths From Source to Target </h2> <h3> 題目 </h3> Given a directed acyclic graph (DAG) of n nodes labeled from 0 to n - 1, find all possible paths from node 0 to node n - 1 and return them in any order. The graph is given as follows: graph[i] is a list of all nodes you can visit from node i (i.e., there is a directed edge from node i to node graph[i][j]). **Example1** ![](https://i.imgur.com/4My2W8P.jpg) ``` Input: graph = [[1,2],[3],[3],[]] Output: [[0,1,3],[0,2,3]] Explanation: There are two paths: 0 -> 1 -> 3 and 0 -> 2 -> 3. ``` <h3> 思路 </h3> 利用Backtracking從node 0一路追蹤到底。 ```python! class Solution(object): def __init__(self): self.ans=[] def allPathsSourceTarget(self, graph): self.traversal(graph,[0]) return self.ans def traversal(self,graph,target): index=target[-1] if len(graph[index])==0 or target[-1]==len(graph)-1: if target[-1]==len(graph)-1: sample=copy.deepcopy(target) self.ans.append(sample) else: for i in xrange(0,len(graph[index])): target.append(graph[index][i]) self.traversal(graph,target) target.pop() """ :type graph: List[List[int]] :rtype: List[List[int]] """ ``` --- <h2> - [O]131.Palindrome Partitioning </h2> <h3> 題目 </h3> Given a string s, partition s such that every substring of the partition is a palindrome. Return all possible palindrome partitioning of s. A palindrome string is a string that reads the same backward as forward. **Example1** ``` Input: s = "aab" Output: [["a","a","b"],["aa","b"]] ``` <h3> 思路 </h3> 從頭開始一個一個慢慢加,如果符合 Palindrome就去跑Backtracking。 ```python! class Solution(object): def __init__(self): self.ans=[] def partition(self, s): self.palidromeProcess([],s) return self.ans def palidromeProcess(self,table,left): if len(left)==0: palidromeAns=copy.deepcopy(table) self.ans.append(palidromeAns) return for i in range(0,len(left)): start=0 end=i flag=0 while start<end: if left[start]==left[end]: start+=1 end-=1 else: flag=-1 break if flag==0: table.append(left[0:i+1]) self.palidromeProcess(table,left[i+1:]) table.pop() """ :type s: str :rtype: List[List[str]] """ ``` --- <h2> - [X]980. Unique Paths III </h2> <h3> 題目 </h3> You are given an m x n integer array grid where grid[i][j] could be: 1 representing the starting square. There is exactly one starting square. 2 representing the ending square. There is exactly one ending square. 0 representing empty squares we can walk over. -1 representing obstacles that we cannot walk over. Return the number of 4-directional walks from the starting square to the ending square, that walk over every non-obstacle square exactly once. **Example1** ![](https://i.imgur.com/kkPgyJ4.jpg) ``` Input: grid = [[1,0,0,0],[0,0,0,0],[0,0,2,-1]] Output: 2 Explanation: We have the following two paths: 1. (0,0),(0,1),(0,2),(0,3),(1,3),(1,2),(1,1),(1,0),(2,0),(2,1),(2,2) 2. (0,0),(1,0),(2,0),(2,1),(1,1),(0,1),(0,2),(0,3),(1,3),(1,2),(2,2) ``` <h3> Discussion </h3> 利用DFS去搜尋所有可能性。 ```python! class Solution(object): def uniquePathsIII(self, A): self.res = 0 m, n, empty = len(A), len(A[0]), 1 for i in range(m): for j in range(n): if A[i][j] == 1: x, y = (i, j) elif A[i][j] == 0: empty += 1 def dfs(x, y, empty): if not (0 <= x < m and 0 <= y < n and A[x][y] >= 0): return if A[x][y] == 2: self.res += empty == 0 return A[x][y] = -2 dfs(x + 1, y, empty - 1) dfs(x - 1, y, empty - 1) dfs(x, y + 1, empty - 1) dfs(x, y - 1, empty - 1) A[x][y] = 0 dfs(x, y, empty) return self.res """ :type grid: List[List[int]] :rtype: int """ ``` --- <h2> - [O]1255. Maximum Score Words Formed by Letters </h2> <h3> 題目 </h3> Given a list of words, list of single letters (might be repeating) and score of every character. Return the maximum score of any valid set of words formed by using the given letters (words[i] cannot be used two or more times). It is not necessary to use all characters in letters and each letter can only be used once. Score of letters 'a', 'b', 'c', ... ,'z' is given by score[0], score[1], ... , score[25] respectively. **Example1** ``` Input: words = ["dog","cat","dad","good"], letters = ["a","a","c","d","d","d","g","o","o"], score = [1,0,9,5,0,0,3,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0] Output: 23 Explanation: Score a=1, c=9, d=5, g=3, o=2 Given letters, we can form the words "dad" (5+1+5) and "good" (3+2+2+5) with a score of 23. Words "dad" and "dog" only get a score of 21. ``` <h3> 思路 </h3> 去枚舉所有可能性,找出最大值。 ```python! class Solution(object): def __init__(self): self.ans=0 def maxScoreWords(self, words, letters, score): table={} for character in letters: if table.get(character)==None: table[character]=1 else: table[character]+=1 for i in xrange(0,len(words)): scoreNow=0 flag=0 copyTable=copy.deepcopy(table) for character in words[i]: scoreNow+=score[ord(character)-ord("a")] if copyTable.get(character)==None: scoreNow=0 flag=-1 break else: if copyTable[character]==0: scoreNow=0 flag=-1 break copyTable[character]-=1 if flag==0: self.ans=max(self.ans,scoreNow) self.checkScore(copyTable,i+1,scoreNow,score,words) return self.ans def checkScore(self,table,startPos,score,scoreTable,words): if startPos>=len(words): return for i in xrange(startPos,len(words)): scoreNow=score flag=0 copyTable=copy.deepcopy(table) for character in words[i]: scoreNow+=scoreTable[ord(character)-ord("a")] if copyTable.get(character)==None: scoreNow=score flag=-1 break else: if copyTable[character]==0: scoreNow=score flag=-1 break copyTable[character]-=1 if flag==0: self.ans=max(self.ans,scoreNow) self.checkScore(copyTable,i+1,scoreNow,scoreTable,words) """ :type words: List[str] :type letters: List[str] :type score: List[int] :rtype: int """ ```