DFS搜索入门专题

全排列

题目描述
排列与组合是常用的数学方法。
先给一个正整数 ( 1 < = n < = 10 )
例如n=3,所有组合,并且按字典序输出:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
输入
输入一个整数n( 1<=n<=10)

输出
输出所有全排列

每个全排列一行,相邻两个数用空格隔开(最后一个数后面没有空格)

class Solution:
    """
    @param: nums: A list of integers.
    @return: A list of permutations.
    """
    def permute(self, nums):
        # write your code here
        def search(nums,lists):
            if(len(nums)==len(lists)):
                self.result.append(lists)
                return
            for i in range(len(nums)):
                if self.flag[i]!=1:
                    self.flag[i]=1
                    search(nums,lists+[nums[i]])
                    self.flag[i]=0

        self.result=[]

        self.flag=[]
        for i in range(len(nums)):
            self.flag.append(0)
        search(nums,[])
        return self.result


s = Solution()
print(s.permute([1,2,3]))

带重复数据的全排列

  1. 字符串的不同排列
    给出一个字符串,找到它的所有排列,注意同一个字符串不要打印两次。

样例
样例 1:

输入:“abb”
输出:
[“abb”, “bab”, “bba”]
样例 2:

输入:“aabb”
输出:
[“aabb”, “abab”, “baba”, “bbaa”, “abba”, “baab”]

class Solution:
    """
    @param str: A string
    @return: all permutations
    """
    def stringPermutation2(self, nums):
        # write your code here
        nums = sorted(nums)
        def search(nums,lists,index):
            if(len(nums)==len(lists)):
                self.result.append(lists)
                return
            for i in range(len(nums)):
                if self.flag[i]==1:
                    continue
                if(i!=0 and nums[i]==nums[i-1] and self.flag[i-1]==0):
                    continue
                elif self.flag[i]!=1:
                    self.flag[i]=1
                    search(nums,lists+nums[i],0)
                    self.flag[i]=0

        self.result=[]

        self.flag=[]
        for i in range(len(nums)):
            self.flag.append(0)
        search(nums,"",0)
        return self.result

s = Solution()
print(s.stringPermutation2(['a','b','b']))

组合输出

题目描述
排列与组合是常用的数学方法,其中组合就是从n个元素中抽出r个元素(不分顺序且r < = n),我们可以简单地将n个元素理解为自然数1,2,…,n,从中任取r个数。
现要求你不用递归的方法输出所有组合。
例如n = 5 ,r = 3 ,所有组合为:
1 2 3
1 2 4
1 2 5
1 3 4
1 3 5
1 4 5
2 3 4
2 3 5
2 4 5
3 4 5
输入
一行两个自然数n、r ( 1 < n < 21,1 < = r < = n )。

输出
所有的组合,每一个组合占一行且其中的元素按由小到大的顺序排列,所有的组合也按字典顺序。

class Solution:
    """
    @param: nums: A list of integers.
    @return: A list of permutations.
    """
    def permute(self, nums,r):
        # write your code here
        def search(nums,lists,index):
            if(r==len(lists)):
                self.result.append(lists)
                return
            for i in range(index,len(nums)):
                if self.flag[i]!=1:
                    self.flag[i]=1
                    search(nums,lists+[nums[i]],i+1)
                    self.flag[i]=0

        self.result=[]

        self.flag=[]
        for i in range(len(nums)):
            self.flag.append(0)
        search(nums,[],0)
        return self.result


s = Solution()
print(s.permute([1,2,3,4,5],3))

数字组合 II

给出一组候选数字©和目标数字(T),找出C中所有的组合,使组合中数字的和为T。C中每个数字在每个组合中只能使用一次。

样例
给出一个例子,候选数字集合为[10,1,6,7,2,1,5] 和目标数字 8 ,

解集为:[[1,7],[1,2,5],[2,6],[1,1,6]]

注意事项
所有的数字(包括目标数字)均为正整数。
元素组合(a1, a2, … , ak)必须是非降序(ie, a1 ≤ a2 ≤ … ≤ ak)。
解集不能包含重复的组合。

class Solution:
    """
    @param num: Given the candidate numbers
    @param target: Given the target number
    @return: All the combinations that sum to target
    """
    def combinationSum2(self, num, target):
        # write your code here
        num = sorted(num)
        def search(num,lists,index):
            for i in range(1,len(num)):
                if(len(lists)==i):
                    if sum(lists)==target:
                        if lists not in self.result:
                            self.result.append(lists)
                        return
            for i in range(index,len(num)):
                if self.flag[i]==1:
                    continue
                if(i!=0 and num[i]==num[i-1] and self.flag[i-1]==0):
                    continue
                if self.flag[i]!=1 and sum(lists+[num[i]])<=target:
                    self.flag[i]=1
                    search(num,lists+[num[i]],i+1)
                    self.flag[i]=0

        self.result=[]

        self.flag=[]
        for i in range(len(num)):
            self.flag.append(0)
        search(num,[],0)
        return self.result


1080. 最大的岛

给定一个由0和1组成的非空二维数组grid,一个岛由一组四联通(上下左右四方向)的1(表示陆地)组成。假定grid的四周都是水。

返回最大的岛。(没有岛则返回0)

样例
样例 1:

输入:
[[0,0,1,0,0,0,0,1,0,0,0,0,0],
[0,0,0,0,0,0,0,1,1,1,0,0,0],
[0,1,1,0,1,0,0,0,0,0,0,0,0],
[0,1,0,0,1,1,0,0,1,0,1,0,0],
[0,1,0,0,1,1,0,0,1,1,1,0,0],
[0,0,0,0,0,0,0,0,0,0,1,0,0],
[0,0,0,0,0,0,0,1,1,1,0,0,0],
[0,0,0,0,0,0,0,1,1,0,0,0,0]]
输出:6。
解释:注意不是11!因为是4方向联通。
样例 2:

输入:[[0,0,0,0,0,0,0,0]]
输出:0

class Solution:
    """
    @param grid: a 2D array
    @return: the maximum area of an island in the given 2D array
    """
    def maxAreaOfIsland(self, grid):
        # Write your code here
        rows = len(grid)
        cols = len(grid[0])
        mask = 1
        res={}
        label_table = []
        for i in range(rows):
            col = cols*[0]
            label_table.append(col)

        def dfs(i, j, mask):
            if i<0 or i>=rows or j<0 or j>=cols or label_table[i][j]!=0 or grid[i][j]!=1:
                return 0
            label_table[i][j] = mask
            ret = 1
            #left right up down search
            ret+=dfs(i, j-1, mask)
            ret+=dfs(i, j+1, mask)
            ret+=dfs(i-1, j, mask)
            ret+=dfs(i+1, j, mask)

            return ret

        max_island = 0
        for i in range(rows):
            for j in range(cols):
                if grid[i][j] == 1 and label_table[i][j] == 0:
                    ret = dfs(i,j, mask)
                    if ret > max_island:
                        max_island = ret
                    res[mask] = ret
                    mask+=1
        
        return max_island

求矩阵连通域

class Solution:
    """
    @param grid: a 2D array
    @return: the maximum area of an island in the given 2D array
    """
    def maxAreaOfIsland(self, grid):
        # Write your code here
        rows = len(grid)
        cols = len(grid[0])
        mask = 1
        res={}
        label_table = []
        for i in range(rows):
            col = cols*[0]
            label_table.append(col)

        def dfs(i, j, mask):
            if i<0 or i>=rows or j<0 or j>=cols or label_table[i][j]!=0 or grid[i][j]!=1:
                return 0
            label_table[i][j] = mask
            ret = 1
            #left right up down search
            ret+=dfs(i, j-1, mask)
            ret+=dfs(i, j+1, mask)
            ret+=dfs(i-1, j, mask)
            ret+=dfs(i+1, j, mask)

            return ret

        for i in range(rows):
            for j in range(cols):
                if grid[i][j] == 1 and label_table[i][j] == 0:
                    ret = dfs(i,j, mask)
                    res[mask] = ret
                    mask+=1
        
        return label_table

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值