Python 刷题(想练python的可以对着刷一刷,持续更新)
来源:互联网 发布:搜索排名优化案例 编辑:程序博客网 时间:2024/09/21 08:52
Surrounded Regions
这道题要求将完全由‘X’包围的‘O’全部置为‘X’,也就是将由‘X’包裹的‘O’连通块全部置为‘X’的意思。在矩阵中找连通块,直接进行bfs就可以,如果有任意的一个‘O’到了边界处,那么这个‘O’连通块就没有被‘X’完全包围,否则则将全部的‘O’置为‘X’。刚开始可能是坐标计算手贱了把X和Y打错了,TLE了,后来改了就过了。
好久没写这种类型的bfs,一时半会儿手生,弱死的节奏啊。
class Solution: # @param board, a 9x9 2D array # Capture all regions by modifying the input board in-place. # Do not return any value. def solve(self, board): if board==None: return n = len(board) if n==0: return m = len(board[0]) vis = [None]*len(board) for i in range(len(board)): vis[i] = [0]*len(board[0]) for i in range(n): for j in range(m): if board[i][j]=='O' and vis[i][j]==0: self.check(board, vis, i, j) def check(self, board, vis, x, y): n = len(board) m = len(board[0]) dir = [(1, 0), (-1, 0), (0, 1), (0, -1)] flag = True q = [] q.append((x, y)) vis[x][y] = 1 while len(q)!=0: curx, cury = q[0] q.remove(q[0]) for i in range(4): tx = curx+dir[i][0] ty = cury+dir[i][1] if tx==-1 or tx==n or ty==-1 or ty==m: flag = False continue if board[tx][ty]=='O' and vis[tx][ty]==0: q.append((tx, ty)) vis[tx][ty] = 1 if flag==False: return q = [] q.append((x, y)) vis[x][y]=2 while len(q)!=0: curx, cury = q[0] q.remove(q[0]) board[curx][cury] = 'X' for i in range(4): tx = curx+dir[i][0] ty = cury+dir[i][1] if tx==-1 or tx==n or ty==-1 or ty==m: pass else: if board[tx][ty]=='O' and vis[tx][ty]!=2: q.append((tx, ty)) vis[tx][ty] = 2
Distinct Subsequences
典型的动态规划,给定串S和T,问S中有多少种可能的子序列使得该子序列正好和T相同。比如说S='aacb',T='ab',那么结果就是2.
这种直观感觉可以通过依次递推上去的,或者说是具有最优子结构性质的问题都是通过动态规划的方法来求解。定义状态dp[i][j]表示T的子串T[0, i]在S子串S[0, j]出现的合法的次数,那么状态转移方程如下:
if T[i] != S[j],dp[i][j]=dp[i][j-1]
else if T[i] == S[j], dp[i][j] = dp[i][j-1] + dp[i-1][j-1]
注意初始化dp[0][j]=1,也就是说任意的空串都在S[0,j]中出现一次。
按照上面的状态转移方程写出代码就行了。
class Solution: # @return an integer def numDistinct(self, S, T): if S==None or T==None: return 0 if len(S)==0 or len(T)==0: return 0 S = '.' + S T = '.' + T dp = [[0]*len(S) for i in range(len(T))] for i in range(len(S)): dp[0][i] = 1 for i in range(1, len(T)): for j in range(i, len(S)): dp[i][j] = dp[i][j-1] if T[i] == S[j]: dp[i][j] += dp[i-1][j-1] return dp[len(T)-1][len(S)-1]#s = Solution()#print(s.numDistinct('rabbbit', 'rabbit'))#print(s.numDistinct('abc', 'ac'))#print(s.numDistinct('abaccac', 'ac'))
Copy List with Random Pointer
这道题还是挺有意思的,咋一看题不知道考点在哪里?看了挺久才理解原来是random指针和深拷贝。所谓为深拷贝是需要重新申请一块内存,使其结构与原链表完全相同。也就是说对应链表中的节点的label值要对应相同,并且random指针指向的对象也要对应到新的对象。
由于需要将原链表中的对象对应到新生成的对象,所以用一个dict来map原来的对象到新的对象。于是进行两遍遍历,第一遍生成新的链表,并且对新链表中的label值和next指针进行赋值,next指针直接指向新生成的下一个对象;第二遍遍历,实现新链表中random指针的赋值。
注意读懂题目,找到问题的trick所在。这道题我是用python写的,可以使用对象名,如果使用C++写的话,对象的标识就是对象的指针了,写法上应该差不多。奉上python代码:
# Definition for singly-linked list with a random pointer.# class RandomListNode:# def __init__(self, x):# self.label = x# self.next = None# self.random = Noneclass Solution: # @param head, a RandomListNode # @return a RandomListNode def copyRandomList(self, head): if head == None: return None myMap = {} nHead = RandomListNode(head.label) myMap[head] = nHead p = head q = nHead while p != None: q.random = p.random if p.next != None: q.next = RandomListNode(p.next.label) myMap[p.next] = q.next else: q.next = None p = p.next q = q.next p = nHead while p!= None: if p.random != None: p.random = myMap[p.random] p = p.next return nHead
Binary Tree Maximum Path Sum
在一棵二叉树中找到任意的一条路径,使得该条路径上的所有节点的值之和最大,该路径可以起始于树中任意节点,终止于树中的任意节点。
初一看显然有点像一个序列的最大连续子段和,这道题其实也有点类似。
我们知道,任意一个合法的路径,必然是通过某个节点,我们称之为root,从左子树的某个节点开始,通过该root走到右子树的某个节点终止达到最大的路径和。那么我们只需要记录从子树某个点开始连续走到当前节点的最大的和就行了,显然如果是走到该节点之前的最大值小于0,那么前面那一段的值就抛弃(丢弃前面一段小于0的路径肯定更优,这个和最大子段和的思路是一样的)。于是我们可以得到通过该节点的最大的子段和为root.val+leftMax+rightMax,然后用该值更新全局最优解就可以了。
奉上代码吧,比较简单。
# Definition for a binary tree node# class TreeNode:# def __init__(self, x):# self.val = x# self.left = None# self.right = Noneclass Solution: #def __init__(self): # self.ans = 0 # @param root, a tree node # @return an integer def maxPathSum(self, root): self.ans = -0xFFFFFFF self.dfs(root) return self.ans def dfs(self, root): if root == None: return 0 if root.left == None and root.right == None: self.ans = max(self.ans, root.val) return root.val leftMax = rightMax = 0 if root.left != None: leftMax = max(0, self.dfs(root.left)) if root.right != None: rightMax = max(0, self.dfs(root.right)) self.ans = max(self.ans, leftMax+rightMax+root.val) return root.val+max(leftMax, rightMax)
- Python 刷题(想练python的可以对着刷一刷,持续更新)
- 小心Python的“坑”(持续更新)
- python基础(持续更新)
- python术语(持续更新)
- Python笔记(持续更新)
- Python 爬虫(持续更新)
- python学习 持续更新
- Python Tips 持续更新
- Python学习--持续更新
- 【Python】Python3.3的不同(持续更新中)
- 实用的Python库(会一直持续更新。。。)
- python中随机数的用法总结 (持续更新)
- python2 与Python 3 的区别(持续更新...)
- python 中常用的图像操作(持续更新)
- Python 里面的一些小技巧(持续更新)
- python 一些有用的功能函数(持续更新)
- Python报错的解决方案(持续更新)
- 破解md5的python代码,持续更新
- android:inputType参数类型说明
- java入门:配置环境变量
- css自动换行
- IP首部的校验和字段是怎么计算的?
- Android 4.0 framework源码修改编译,模拟器运行不起来——解决
- Python 刷题(想练python的可以对着刷一刷,持续更新)
- nil,Nil和NULL的分别
- 记一次奇怪的ORA-04028: cannot generate diana for object
- oracle SQL高级使用总结
- android之定时发送短信消息
- 2D绘图
- 对不起,请将 php.ini 中的 short_open_tag 设置为 On,否则无法继续安装
- Linux 强制重启
- [LeetCode] Longest Palindromic Substring 最长回文子串