文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Python 刷题(想练python的可

2023-01-31 02:07

关注

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 = None

class 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 = None

class 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)
        

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯