leetcode 解题报告(37-40)

37. Sudoku Solver

题目描述: 填数独,36题的升级版。
在这里插入图片描述
解题思路: DFS求解,解题逻辑就是先找个一个空格的位置,然后在这个位置上填入一个有效的数字,意味着填入的数值满足数独的三个约束条件,但是并不见得就是最终的答案,所以还需要递归验证,在填入这个数字的基础上,找到下一个空格,继续填入一个有效数字,一直往下验证,直到不符合条件时,修改填入的数字,再重新验证,直到找到最终的答案。不过时间复杂度比较高,因为选择了最暴力的解法而没有做优化。在一些细节上卡了很久,结果这道题花了两三个小时的时间。

AC代码:

# python
class Solution(object):
    def solveSudoku(self,board):
        self.board = board
        self.find_soluiton()
        return self.board

    def find_soluiton(self):
        x,y = -1,-1
        i = 0
        for i in range(0,9): # 查找空格位置
            if '.' in self.board[i]:
                x,y = i,self.board[i].index('.')
                break
        if x == -1 and y == -1: # 没有空格则求得最终解,程序结束。
            return True
        for i in range(1,10):
            self.board[x][y] = str(i) # 随机填一个数字
            if (self.is_valid(self.board[x]) and self.is_valid([self.board[j][y] for j in range(9)]) and self.is_valid([self.board[int(x/3)*3+j][int(y/3)*3+k] for j in range(3) for k in range(3)])): # 检查有效性 分别检查行,列,以及小方块,使用列表推倒式从9X9的矩阵里提取9个数待验证。
                if self.find_soluiton(): # 递归求解
                    return True
                else:
                    self.board[x][y] = '.'
            else:
                self.board[x][y] = '.'
        return False
    
    def is_valid(self,tmp): # 检查有效性
        return  len(set(tmp)) == 9 or 10-tmp.count('.') == len(set(tmp)) # 利用集合元素不重复的性质

38. Count and Say

题目描述: 奈何我着实读不懂题目,求助了评论才看懂题目在说啥。原题如下:
数数并把他说出来? 就是第一个字符是1从第二个字符串开始,数上一个字符串的数,比如有一个1,把个字省了就是“11”,然后第三行,数上一行的数,两个1,省略个字,得到“2 1”,第四行数第三行的数,一个1,一个2,两个1,于是就有了“11 12 21”,剩下的以此类推,题目给一个数n,让给出第n行的字符串。
在这里插入图片描述
解题思路: 简单模拟,直接先把30种情况全列出来,就一行一行推,然后到里面去取就是了。

AC代码:

# python
class Solution(object):
    def countAndSay(self,n):
        res = ["1"] # 情况列表
        cnt = 0
        for i in res:
            tmp = ""
            l,r = 0,0
            while l <= r and r < len(i): # 递推列举每种情况
                while r < len(i) and i[l] == i[r]:
                    r += 1
                tmp += str(r-l)+i[l]
                l = r
            res.append(tmp)
            cnt += 1
            if (cnt == 30):
                break
        return res[n-1]

39. Combination Sum

题目描述: 给定一个无序数组和一个目标值,要求从数组中取出若干个元素使得和等于目标值,数组元素不重复。

解题思路: 自己想想了很久没有想出来,总是会超时。后来看了别人的代码,发现用dfs很快就解出来了。

AC代码:

# python
class Solution(object):
    def combinationSum(self, candidates, target):
        res = []
        self.dfs(candidates, target, 0, [],res)
        return res
        
    def dfs(self ,nums ,target ,index ,path ,res):
        if target < 0: 
            return
        if target == 0: # 记录结果
            res.append(path)
            return
        for i in xrange(index,len(nums)):
            self.dfs(nums, target-nums[i],i, path + [nums[i]],res)

40. Combination Sum II

题目描述: 和上一题类似的题干,只不过难度稍微升级了一些,数组中存在重复元素。

解题思路: 和上一题的思路一样,用dfs求解,不过这就存在一个问题,因为题目变成了数组中有重复值,这就会导致搜索的时候,回反复搜到那些重复的值,在dfs入口的地方先对下标做一个加一的操作,这样就不会搜到自身了,然后再在记录结果的地方,删掉重复的结果,就能得出正确答案了。

AC代码:

# python
class Solution(object):
    def combinationSum2(self, candidates, target):
        res = []
        candidates.sort()
        self.dfs(candidates, target,-1, [],res)
        return res
        
    def dfs(self ,nums ,target ,index ,path ,res):
        index += 1
        if target < 0: 
            return
        if target == 0: # 记录结果
            if path not in res: # 删掉重复结果
                res.append(path)
            return
        for i in xrange(index,len(nums)):
            self.dfs(nums, target-nums[i],i, path + [nums[i]],res)

No. xx

题目描述: 模板

解题思路: 模板

AC代码:

###

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值