回溯法

  1. 有效的數獨
    解題思路:記錄某行、某列、3x3 宮格內數字
class Solution:
    def isValidSudoku(self, board):
        """
        :type board: List[List[str]]
        :rtype: bool
        """
        rows = [{} for i in range(9)]
        columns = [{} for i in range(9)]
        boxes = [{} for i in range(9)]

        # validate a board
        for i in range(9):
            for j in range(9):
                num = board[i][j]
                if num != '.':
                    num = int(num)
                    box_index = (i // 3 ) * 3 + j // 3
                    
                    # keep the current cell value
                    rows[i][num] = rows[i].get(num, 0) + 1
                    columns[j][num] = columns[j].get(num, 0) + 1
                    boxes[box_index][num] = boxes[box_index].get(num, 0) + 1
                    
                    # check if this value has been already seen before
                    if rows[i][num] > 1 or columns[j][num] > 1 or boxes[box_index][num] > 1:
                        return False         
        return True
  1. 組合總和

給定一個無重複元素的數組 candidates 和一個目標數 target ,找出 candidates 中所有可以使數字和爲 target 的組合。

candidates 中的數字可以無限制重複被選取。

解題思路:
題目分析:本題採用遞歸較容易解答。首先,將數組內的元素由小到大排序,然後不斷地進行試探,直到和爲target。若當前和小於target,則繼續往裏面加元素;若當前和等於target,就可以將結果保留下來;若當前和已經大於target,那就可以排除掉這種情況,回溯到上一層,尋找其他可能的組合。本質上我覺得可以歸納爲深度搜索。

代碼如下:

class Solution(object):
    def combinationSum(self, candidates, target):
        """
        :type candidates: List[int]
        :type target: int
        :rtype: List[List[int]]
        """
        candidates.sort()
        n = len(candidates)
        res = []
        def backtrack(i, tmp_sum, tmp):
            if  tmp_sum > target or i == n:
                return 
            if tmp_sum == target:
                res.append(tmp)
                return 
            for j in range(i, n):
                if tmp_sum + candidates[j] > target:
                    break
                backtrack(j,tmp_sum + candidates[j],tmp+[candidates[j]])
        backtrack(0, 0, [])
        return res
  1. 組合總和 II

給定一個數組 candidates 和一個目標數 target ,找出 candidates 中所有可以使數字和爲 target 的組合。

candidates 中的每個數字在每個組合中只能使用一次。

參考: https://zhuanlan.zhihu.com/c_1047791597869199360
解題代碼:

class Solution(object):
    def combinationSum2(self, candidates, target):
        """
        :type candidates: List[int]
        :type target: int
        :rtype: List[List[int]]
        """
        if not candidates:
            return []
        candidates.sort()
        n = len(candidates)
        res = []

        def backtrack(i, tmp_sum, tmp_list):
            if tmp_sum == target:
                res.append(tmp_list)
                return 
            for j in range(i, n):
                if tmp_sum + candidates[j]  > target : break
                if j > i and candidates[j] == candidates[j-1]:continue
                backtrack(j + 1, tmp_sum + candidates[j], tmp_list + [candidates[j]])
        backtrack(0, 0, [])    
        return res
  1. 全排列

給定一個沒有重複數字的序列,返回其所有可能的全排列。

解題思路: 使用一個和nums長度一樣的數列,記錄是否使用到這個元素,使用到以後把這個數列對應的位置改爲True

解題代碼:

class Solution(object):
    def permute(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
    
        mark=[False]*len(nums)
        outcome=[]
        curr=[]
        self.core(mark,nums,curr,outcome)
        return outcome

    def core(self,mark,nums,curr,outcome):
        if sum(mark)==len(nums):
            outcome.append(curr[:])
        for i in range(len(nums)):
            if mark[i]:
                continue
            curr.append(nums[i])
            mark[i]=True
            self.core(mark,nums,curr,outcome)
            mark[i]=False
            curr.pop()

  1. 全排列 II

給定一個可包含重複數字的序列,返回所有不重複的全排列。

class Solution(object):
    def permuteUnique(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        ans = [[]]
        for n in nums:
            ans = [l[:i]+[n]+l[i:] 
                for l in ans
                   for i in range((l+[n]).index(n)+1)]
                  #排除重複排列
        return ans
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章