Leetcode 中等难度题型

86. 分隔链表

已解答
中等
相关标签
相关企业
给你一个链表的头节点 head 和一个特定值 x ,请你对链表进行分隔,使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。

你应当 保留 两个分区中每个节点的初始相对位置。

示例 1:

输入:head = [1,4,3,2,5,2], x = 3
输出:[1,2,2,4,3,5]

class Solution:
    def partition(self, head: Optional[ListNode], x: int) -> Optional[ListNode]:
        a,b=[],[]
        dummy=head
        while dummy:
            if dummy.val<x:
                a.append(dummy.val)
            else:
                b.append(dummy.val)
            dummy=dummy.next
        dummy=head
        for i in a+b:
            dummy.val=i
            dummy=dummy.next
        return head

946. 验证栈序列

已解答
中等
相关标签
相关企业
给定 pushed 和 popped 两个序列,每个序列中的 值都不重复,只有当它们可能是在最初空栈上进行的推入 push 和弹出 pop 操作序列的结果时,返回 true;否则,返回 false 。

示例 1:

输入:pushed = [1,2,3,4,5], popped = [4,5,3,2,1]
输出:true
解释:我们可以按以下顺序执行:
push(1), push(2), push(3), push(4), pop() -> 4,
push(5), pop() -> 5, pop() -> 3, pop() -> 2, pop() -> 1
示例 2:

class Solution:
    def validateStackSequences(self, pushed: List[int], popped: List[int]) -> bool:
        for i in range(len(popped)-1):
            ind=pushed.index(popped[i])
            if ind-1 > pushed.index(popped[i+1]):
                return False
            del pushed[ind]
        return True

729. 我的日程安排表 I

已解答
中等
相关标签
相关企业
提示
实现一个 MyCalendar 类来存放你的日程安排。如果要添加的日程安排不会造成 重复预订 ,则可以存储这个新的日程安排。

当两个日程安排有一些时间上的交叉时(例如两个日程安排都在同一时间内),就会产生 重复预订 。

日程可以用一对整数 start 和 end 表示,这里的时间是半开区间,即 [start, end), 实数 x 的范围为, start <= x < end 。

实现 MyCalendar 类:

MyCalendar() 初始化日历对象。
boolean book(int start, int end) 如果可以将日程安排成功添加到日历中而不会导致重复预订,返回 true 。否则,返回 false 并且不要将该日程安排添加到日历中。

示例:

输入:
[“MyCalendar”, “book”, “book”, “book”]
[[], [10, 20], [15, 25], [20, 30]]
输出:
[null, true, false, true]

class MyCalendar:

    def __init__(self):
        self.l=[]

    def book(self, start: int, end: int) -> bool:
        if not self.l:
            self.l.append([start,end])
            return True
        else:
            self.l.append([start,end])
            self.l.sort()
            if 0<self.l.index([start,end])<len(self.l)-1:
                if self.l[self.l.index([start,end])-1][1]<=start and self.l[self.l.index([start,end])+1][0] >= end:
                    return True
            elif 0== self.l.index([start,end]):
                if self.l[self.l.index([start,end])+1][0] >=end:
                    return True
            elif self.l.index([start,end])==len(self.l)-1:
                if self.l[self.l.index([start,end])-1][1] <=start:
                    return True                
            self.l.remove([start,end])
            return False


554. 砖墙

中等
相关标签
相关企业
你的面前有一堵矩形的、由 n 行砖块组成的砖墙。这些砖块高度相同(也就是一个单位高)但是宽度不同。每一行砖块的宽度之和相等。

你现在要画一条 自顶向下 的、穿过 最少 砖块的垂线。如果你画的线只是从砖块的边缘经过,就不算穿过这块砖。你不能沿着墙的两个垂直边缘之一画线,这样显然是没有穿过一块砖的。

给你一个二维数组 wall ,该数组包含这堵墙的相关信息。其中,wall[i] 是一个代表从左至右每块砖的宽度的数组。你需要找出怎样画才能使这条线 穿过的砖块数量最少 ,并且返回 穿过的砖块数量 。

示例 1:

输入:wall = [[1,2,2,1],[3,1,2],[1,3,2],[2,4],[3,1,2],[1,3,1,1]]
输出:2
示例 2:

输入:wall = [[1],[1],[1]]
输出:3

#超时!!可以减去数组中最小值做优化
class Solution:
    def leastBricks(self, wall: List[List[int]]) -> int:
        a,b,c,nums=inf,[],sum(wall[0]),0
        if all(len(wall[k]) == 1 for k in range(len(wall))):
            return len(wall)
        elif all(wall[k] == wall[k+1] for k in range(len(wall)-1)):
            return 0
        for i in range(c-1):
            for j in range(len(wall)):
                if 1 == wall[j][0]:
                    del wall[j][0]
                else:
                    wall[j][0]=wall[j][0]-1
                    nums+=1
            a=min(a,nums)
            nums=0
        return a


752. 打开转盘锁

尝试过
中等
相关标签
相关企业
提示
你有一个带有四个圆形拨轮的转盘锁。每个拨轮都有10个数字: ‘0’, ‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’ 。每个拨轮可以自由旋转:例如把 ‘9’ 变为 ‘0’,‘0’ 变为 ‘9’ 。每次旋转都只能旋转一个拨轮的一位数字。

锁的初始数字为 ‘0000’ ,一个代表四个拨轮的数字的字符串。

列表 deadends 包含了一组死亡数字,一旦拨轮的数字和列表里的任何一个元素相同,这个锁将会被永久锁定,无法再被旋转。

字符串 target 代表可以解锁的数字,你需要给出解锁需要的最小旋转次数,如果无论如何不能解锁,返回 -1 。

示例 1:

输入:deadends = [“0201”,“0101”,“0102”,“1212”,“2002”], target = “0202”
输出:6
解释:
可能的移动序列为 “0000” -> “1000” -> “1100” -> “1200” -> “1201” -> “1202” -> “0202”。
注意 “0000” -> “0001” -> “0002” -> “0102” -> “0202” 这样的序列是不能解锁的,
因为当拨动到 “0102” 时这个锁就会被锁定。

#通过33 / 48 要看极端情况
class Solution:
    def openLock(self, deadends: List[str], target: str) -> int:
        a,b,c,f=0,[0,0,0,0],0,False
        for i in range(len(target)):
            if target[i] != "0":
                b[i] = 10 if int(target[i]) > 5 else 0
                while b[i] != int(target[i]):
                    if int(target[i]) <= 5:
                        b[i] =int(b[i])+1
                        a+=1
                        if "".join(map(str,b)) in deadends:
                            a+=2
                        print(b[i])         
                    else:
                        b[i] =int(b[i])-1
                        a+=1
                        if "".join(map(str,b)) in deadends:
                            for k in range(i):
                                for m in (1,-1):
                                    b[k]+=m
                                    if "".join(map(str,b)) not in deadends:
                                        print(b)
                                        a+=2
                                        f=True
                                        break                                    
                                    b[k]-=m
                                if f:
                                    break
                            if not f:
                                return -1   
                                   
            else:
                b[i] = 0
        return a


38. 外观数列

已解答
中等
相关标签
相关企业
提示
给定一个正整数 n ,输出外观数列的第 n 项。

「外观数列」是一个整数序列,从数字 1 开始,序列中的每一项都是对前一项的描述。

你可以将其视作是由递归公式定义的数字字符串序列:

countAndSay(1) = “1”
countAndSay(n) 是对 countAndSay(n-1) 的描述,然后转换成另一个数字字符串。
前五项如下:

  1. 1
    
  2. 11
    
  3. 21
    
  4. 1211
    
  5. 111221
    

第一项是数字 1
描述前一项,这个数是 1 即 “ 一 个 1 ”,记作 “11”
描述前一项,这个数是 11 即 “ 二 个 1 ” ,记作 “21”
描述前一项,这个数是 21 即 “ 一 个 2 + 一 个 1 ” ,记作 “1211”
描述前一项,这个数是 1211 即 “ 一 个 1 + 一 个 2 + 二 个 1 ” ,记作 “111221”
要 描述 一个数字字符串,首先要将字符串分割为 最小 数量的组,每个组都由连续的最多 相同字符 组成。然后对于每个组,先描述字符的数量,然后描述字符,形成一个描述组。要将描述转换为数字字符串,先将每组中的字符数量用数字替换,再将所有描述组连接起来。

例如,数字字符串 “3322251” 的描述如下图:

示例 1:

输入:n = 1
输出:“1”
解释:这是一个基本样例。

class Solution:
    def countAndSay(self, n: int) -> str:
        dp=["0"]*n
        dp[0]="1"
        a,b,c=0,[],[]
        if n ==1:
            return "1"
        for i in range(1,n):
            for j in range(len(dp[i-1])):
                if dp[i-1][j] not in b:
                    if b:
                        c.append(str(len(b))+b[0])
                        b=[]                       
                    b.append(dp[i-1][j])
                else:
                    b.append(dp[i-1][j])
                if j == len(dp[i-1])-1:
                    c.append(str(len(b))+b[0])
                    b=[]
            dp[i]="".join(c)
            c=[] 
        return dp[i]  

62. 不同路径

已解答
中等
相关标签
相关企业
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。

机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。

问总共有多少条不同的路径?

示例 1:

输入:m = 3, n = 7
输出:28
示例 2:

class Solution:
    def uniquePaths(self, m: int, n: int) -> int:
        dp=[[0] * n for _ in range(m)]
        for i in range(m):
            dp[i][0] = 1
        for j in range(n):
            dp[0][j] = 1
        for i in range(1,m):
            for j in range(1,n):
                dp[i][j] = dp[i-1][j] + dp[i][j-1]
        return dp[-1][-1]

63. 不同路径 II

已解答
中等
相关标签
相关企业
提示
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。

机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish”)。

现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径?

网格中的障碍物和空位置分别用 1 和 0 来表示。

示例 1:

输入:obstacleGrid = [[0,0,0],[0,1,0],[0,0,0]]
输出:2
解释:3x3 网格的正中间有一个障碍物。
从左上角到右下角一共有 2 条不同的路径:

  1. 向右 -> 向右 -> 向下 -> 向下
  2. 向下 -> 向下 -> 向右 -> 向右
class Solutin:
    def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int:

        m ,n= len(obstacleGrid),len(obstacleGrid[0])
        dp=[[0] * n for _ in range(m)]
        if obstacleGrid[0][0] == 1:
            return 0
        for i in range(m):
            if obstacleGrid[i][0] != 1:
                dp[i][0] = dp[i-1][0] if i > 0 else 1
            else:
                dp[i][0] = 0
        for j in range(n):
            if obstacleGrid[0][j] != 1:
                dp[0][j] = dp[0][j-1] if j > 0 else 1
            else:
                dp[0][j] = 0
        for i in range(1,m):
            for j in range(1,n):
                if obstacleGrid[i][j] != 1:

                    dp[i][j] = dp[i-1][j] + dp[i][j-1]
                else:
                    dp[i][j] = 0
        return dp[-1][-1]

75. 颜色分类

已解答
中等
相关标签
相关企业
提示
给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums ,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。

我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。

必须在不使用库内置的 sort 函数的情况下解决这个问题。

示例 1:

输入:nums = [2,0,2,1,1,0]
输出:[0,0,1,1,2,2]
示例 2:

输入:nums = [2,0,1]
输出:[0,1,2]

class Solution:
    def sortColors(self, nums: List[int]) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        a,b,c=0,0,[]
        while a < len(nums):
            if nums[a] == 2:
                del nums[a]
                nums.append(2)
            elif nums[a]==0:
                del nums[a]
                nums.insert(0,0)
                a+=1
            else:
                a+=1
            if len(nums) - nums.count(2) == a:
                break

3. 无重复字符的最长子串

已解答
中等
相关标签
相关企业
给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。

示例 1:

输入: s = “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
示例 2:

输入: s = “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。
示例 3:

输入: s = “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。
请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。

class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        b=[]
        if not s:return 0
        for i in range(len(s)):
            a=0
            tmp=i
            while i <= len(s)-1 and s[i] not in s[tmp:i]:
                a+=1
                i+=1
            b.append(a)
        return max(b)

7. 整数反转

已解答
中等
相关标签
相关企业
给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。

如果反转后整数超过 32 位的有符号整数的范围 [−231, 231 − 1] ,就返回 0。

假设环境不允许存储 64 位整数(有符号或无符号)。

示例 1:

输入:x = 123
输出:321
示例 2:

输入:x = -123
输出:-321
示例 3:

输入:x = 120
输出:21
示例 4:

输入:x = 0
输出:0

class Solution:
    def reverse(self, x: int) -> int:
        if x >= 0:
            if -2**31<int(str(x)[::-1]) <=2**31-1:
                return int(str(x)[::-1])
            else:
                return 0
        else:
            if -2**31<int(str(x)[1:][::-1]) <=2**31-1:
                return -int(str(x)[1:][::-1])
            else:
                return 0    

8. 字符串转换整数 (atoi)

已解答
中等
相关标签
相关企业
请你来实现一个 myAtoi(string s) 函数,使其能将字符串转换成一个 32 位有符号整数(类似 C/C++ 中的 atoi 函数)。

函数 myAtoi(string s) 的算法如下:

读入字符串并丢弃无用的前导空格
检查下一个字符(假设还未到字符末尾)为正还是负号,读取该字符(如果有)。 确定最终结果是负数还是正数。 如果两者都不存在,则假定结果为正。
读入下一个字符,直到到达下一个非数字字符或到达输入的结尾。字符串的其余部分将被忽略。
将前面步骤读入的这些数字转换为整数(即,“123” -> 123, “0032” -> 32)。如果没有读入数字,则整数为 0 。必要时更改符号(从步骤 2 开始)。
如果整数数超过 32 位有符号整数范围 [−231, 231 − 1] ,需要截断这个整数,使其保持在这个范围内。具体来说,小于 −231 的整数应该被固定为 −231 ,大于 231 − 1 的整数应该被固定为 231 − 1 。
返回整数作为最终结果。
注意:

本题中的空白字符只包括空格字符 ’ ’ 。
除前导空格或数字后的其余字符串外,请勿忽略 任何其他字符。

示例 1:

输入:s = “42”
输出:42
解释:加粗的字符串为已经读入的字符,插入符号是当前读取的字符。
第 1 步:“42”(当前没有读入字符,因为没有前导空格)
^
第 2 步:“42”(当前没有读入字符,因为这里不存在 ‘-’ 或者 ‘+’)
^
第 3 步:“42”(读入 “42”)
^
解析得到整数 42 。
由于 “42” 在范围 [-231, 231 - 1] 内,最终结果为 42 。

class Solution:
    def myAtoi(self, s: str) -> int:
        s = s.strip()   
        pre,tre,beg="+","",0
        if not s:
            return 0
        if s[0] in "+-":
            pre = s[0]
            beg = 1
        for i in range(beg,len(s)):
            if s[i] not in "0123456789":
                break
            elif s[i] in "0123456789":
                tre+=str(s[i])
        if tre:
            if -2**31 <= int(pre+tre) <= 2**31-1:
                return int(pre+tre) if tre else 0
            else:
                return 2**31-1 if pre == "+" else -2**31
        else:
            return 0
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值