第二周leetcode刷题打卡

week2

day1

1.两数相加(⭐️⭐️)

1.1 题目

有两个非空链表,分别表示两个非负整数(num>=0)。表内数字元素逆序存储,并且每个节点只能存储一位数字。

要求将两数相加,并以相同形式返回一个表示和的链表。

提示:可假设除数字 0 之外,这两个数都不会以 0 开头。

1.2 算法思路

链表是逆序存储的,故按顺序依次将两个节点相加并将结果放置于新链表对应节点即可。

按位相加时,有三种情况:

(1)两个链表待加数位上都有数字

(2)一个有,一个没有

(3)两个都没有,但有上个数位相加的不为0的进位

三种情况,都可执行 carry += (l1.val if l1 else 0)+(l2.val if l2 else 0)

然后后移指针变量carry,l1,l2的位置

1.3 流程图

在这里插入图片描述

1.4 代码实现

时间复杂度:O(max(m,n))

空间复杂度:O(n)

# Definition for singly-linked list.
# class ListNode:
    # def __init__(self, val=0, next=None):
    #     self.val = val
    #     self.next = next

## 逐位迭代计算
class Solution:
    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:
        dummy = cur = ListNode()
        carry = 0
        while l1 or l2 or carry:
            carry += (l1.val if l1 else 0)+(l2.val if l2 else 0)
            cur.next =ListNode(carry%10)
            cur = cur.next
            carry //=10
            if l1: l1 = l1.next
            if l2: l2 = l2.next
        return dummy.next

2.无重复字符的最长子串(⭐️⭐️)

2.1 题目

给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。

示例 1:

输入: s = "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3
2.2 算法思路

方法一:找出所有的不含有重复字符的字串,再选出最大长度返回

eg:abcabcaa

两层循环寻找非重复子串。

1.自左向右遍历字符串 指针为i.

2.自i向后遍历字符串,指针为j.

设指针 i 指向字串的首字符,指针 j 指向字串的尾字符。

并设置一个列表str1用于存储检索到的子串以及一个变量max_count,用于后面循环退出时的字串长度计算和最长字串长度的保存。

在每次循环结束,将检索到的非重复字串的长度与已保存的最长子串长度进行比较,将较大值填入max_count.

(a)bcabcaa -> abc 3

a(b)cabcaa -> bca 3

ab©abcaa -> cab 3

abc(a)bcaa -> abc 3

abca(b)caa -> bca 3

abcab©aa -> ca 2

abcabc(a)a -> a 1

abcabca(a) -> a 1

时间复杂度:O(n^2)

方法二:找出最长的字符串,输出长度

2.3 流程图
2.4 代码实现

方法一:

时间复杂度:O(n^2)

空间复杂度:O(n)

class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        str1 = []
        max_length = 0
        count = 0
        for i in range(len(s)):
            for j in range(i,len(s)):
                if s[j] not in str1:
                    str1.append(s[j])
                    count+=1
                else:
                    break
            if max_length < count: 
                max_length = count
            str1.clear()
            count = 0

        return max_length

方法二:


day2

1. 寻找两个正序数组的中位数(⭐️⭐️⭐️)

1.1 算法思路

条件:

已知输入为两个正序数组,设为nums1,nums2.大小分别为m,n.

要求 编写 一个函数能返回 两个数组合并后的中位数

时间复杂度:O(log(m+n))

分析:

大致分为两步:

  • 1.Merge(nums1,nums2)
    • 该步骤也可分为
      • 边排序边合并
        • 时间复杂度 : O(m+n)
      • 先合并再排序
        • 时间复杂度 = max(合并算法的时间复杂度+排序算法的时间复杂度)
  • 2.return (nums[len/2]+nums[len/2-1])/2 if len%2 else nums[len/2-1]
1.2流程图

在这里插入图片描述

1.3 代码实现
class Solution:
    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
        m = len(nums1)		#数组1的大小
        n = len(nums2)		#数组2的大小

        num = []			#用于存储合并后的数组
        
        # 1.在存在空数组的情况下的寻找中位数
        if not nums2 :
            if len(nums1)%2==0:
                return (nums1[int(len(nums1)/2)] + nums1[int(len(nums1)/2)-1])/2
            else :
                return nums1[int(len(nums1)/2)]
        
        if not nums1 :
            if len(nums2)%2==0:
                return (nums2[int(len(nums2)/2)] + nums2[int(len(nums2)/2)-1])/2
            else :
                return nums2[int(len(nums2)/2)]
            
        # 2.在不存在空数组的情况下的寻找中位数
        i = j = 0			#分别用于遍历数组1,2的索引
        
        while len(num)!=(m+n):
            # 2.1 当某个数组已被遍历完时的情况
            if i==m :
                while (j!=n):
                    num.append(nums2[j])
                    j+=1
    
            if j==n:
                while (i!=m):
                    num.append(nums1[i])
                    i+=1
            # 2.2 两个数组都未被遍历完的情况
            else:
                if(nums1[i]<=nums2[j]):
                    num.append(nums1[i])
                    i+=1
                else:
                    num.append(nums2[j])
                    j+=1
            
        if len(num)%2==0:
            return (num[int(len(num)/2)] + num[int(len(num)/2)-1])/2
        else :
            return num[int(len(num)/2)]

2. 最长回文子串(⭐️⭐️)

2.1 暴力法

算法思路:

(1)枚举出字符串中所有的子串

(2)从所有子串中筛选出回文串

(3)返回最长的回文串

流程图:

代码实现:

#判断是否回文串
def huiwen(s:str)->int:
    if len(s) == 1:
        return 1

    if len(s)%2==0:
        i = 0
        j = -1
        while(i+1-j <= len(s)):
            if(s[i]!=s[j]):
                return 0
            i+=1
            j-=1
        return 1
    
    else:
        i = 0
        j = -1
        while(i+1-j<=len(s)-1):
            if(s[i]!=s[j]):
                return 0
            i+=1
            j-=1
        return 1


class Solution:
    def longestPalindrome(self, s: str) -> str:
        # 1. 暴力法
        # 1.1 找出所有字串并存入A1中
        A1 = []
        for i in range(len(s)):
            t = s[i]
            A1.append(t)
            for j in range(i+1,len(s)):
                t += s[j]
                A1.append(t)

        # 1.2 从所有子串中找出回文串
        max_len = 0
        max_s = "" 
        for a in A1:
            if huiwen(a)==1:
                if len(a)>max_len:
                    max_len = len(a)
                    max_s = a

        return max_s

        

                

时间复杂度空间复杂度
O(n^3)O(n)

2.2 中心扩展法

算法思路:

(1)从左到右遍历整个数组,每次扫描到一个元素时,进行步骤(2)

(2)设两个指针i,j分别指向该元素。

(3)判断i的左部节点s[i-1]与j的右方相邻节点s[j+1]是否存在,若不存在或存在但不相等,len = j-i+1.否则分别向左右移动

class Solution:
    def expandAroundCenter(self, s, left, right):
        while left >= 0 and right < len(s) and s[left] == s[right]:
            left -= 1
            right += 1
        return left + 1, right - 1

    def longestPalindrome(self, s: str) -> str:
        start, end = 0, 0
        for i in range(len(s)):
            left1, right1 = self.expandAroundCenter(s, i, i)#检测奇数回文串
            left2, right2 = self.expandAroundCenter(s, i, i + 1)#检测偶数回文串
            
            if right1 - left1 > end - start:
                start, end = left1, right1
            if right2 - left2 > end - start:
                start, end = left2, right2
        return s[start: end + 1]

			
					
			
时间复杂度空间复杂度
O(n^2)O(1)
2.3 动态规划法

动态规划法属于分治法思路的一种方法
核心在于将一个问题划分为多个子问题

class Solution:
    def longestPalindrome(self, s: str) -> str:
        n = len(s)# 字符串长度

        if n < 2:
            return s
        
        max_len = 1
        begin = 0 #左指针
        # dp[i][j] 表示 s[i..j] 是否是回文串
        dp = [[False] * n for _ in range(n)]
        for i in range(n):
            dp[i][i] = True
        
        # 递推开始
        # 先枚举子串长度
        for L in range(2, n + 1):
            # 枚举左边界,左边界的上限设置可以宽松一些
            for i in range(n):
                # 由 L 和 i 可以确定右边界,即 j - i + 1 = L 得
                j = L + i - 1
                # 如果右边界越界,就可以退出当前循环
                if j >= n:
                    break
                    
                if s[i] != s[j]:
                    dp[i][j] = False 
                else:
                    if j - i < 3:
                        dp[i][j] = True
                    else:
                        dp[i][j] = dp[i + 1][j - 1]
                
                # 只要 dp[i][L] == true 成立,就表示子串 s[i..L] 是回文,此时记录回文长度和起始位置
                if dp[i][j] and j - i + 1 > max_len:
                    max_len = j - i + 1
                    begin = i
        return s[begin:begin + max_len]

day3

1. N 字形变换(⭐️⭐️)

将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。

比如输入字符串为 “PAYPALISHIRING” 行数为 3 时,排列如下:

P   A   H   N
A P L S I I G
Y   I   R

之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:“PAHNAPLSIIGYIR”。

请你实现这个将字符串进行指定行数变换的函数:

string convert(string s, int numRows);
1.1 算法思路:
1.2 流程图:
1.3 代码:
class Solution:
    def convert(self, s: str, numRows: int) -> str:
        n = len(s)

        if n<=numRows or numRows==1: return s
        
        res = ["" for _ in range(numRows)]
        i = 0
        flag = -1

        for c in s:
            print(i)
            res[i]+=c
            
            if i==numRows-1 or i ==0 : flag = -flag
            
            i+=flag

        ans = ''
        for r in res:
            ans+=r
        
        return ans

2.整数反转(⭐️⭐️)

给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。

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

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

2.1 算法思路:
2.2 流程图:
2.3 代码:
class Solution:
    def reverse(self, x: int) -> int:
        INT_MIN, INT_MAX = -2**31, 2**31 - 1

        rev = 0
        while x != 0:
            # INT_MIN 也是一个负数,不能写成 rev < INT_MIN // 10
            if rev < INT_MIN // 10 + 1 or rev > INT_MAX // 10:
                return 0
            digit = x % 10
            # Python3 的取模运算在 x 为负数时也会返回 [0, 9) 以内的结果,因此这里需要进行特殊判断
            if x < 0 and digit > 0:
                digit -= 10

            # 同理,Python3 的整数除法在 x 为负数时会向下(更小的负数)取整,因此不能写成 x //= 10
            x = (x - digit) // 10
            rev = rev * 10 + digit
        
        return rev

day4

1.字符串转换整数 (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 的整数应该被固定为 2**31 − 1 。

  • 返回整数作为最终结果。

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

1.1 算法思路
1.2 流程图
1.3 代码实现
class Solution:
    def myAtoi(self, s: str) -> int:
    	# string.lstrip()去前置空格
        s, ans, flag = s.lstrip(), 0, 1
        # 检测是否为空
        if s == "": 
            return 0
        #检测符号位,只有首个有效,并切片
        if   s[0] == '+': 
            s = s[1:]            
        elif s[0] == '-': 
            flag, s = -1, s[1:]
        # 一个符合题目要求的字符串此时应该是数字部分
        for c in s:
            if c.isdigit(): 
                ans = ans * 10 + int(c)
            else: 
                break
        ans *= flag
        return min(max(ans, - 1 << 31), (1 << 31) - 1)

2. 盛最多水的容器(⭐️⭐️)

给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。

找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

返回容器可以储存的最大水量。

说明:你不能倾斜容器。

2.1 算法思路

方法一:暴力解法(枚举)
n个垂线,两两组合,共有n(n-1)/2种非重复结果
两垂线同x轴构成的容器容积大小为:min(height[left],height[right])*(right-left)
时间复杂度高
方法二:借用双指针只遍历一遍(优化)

  • 设立两个指针变量left , right
  • 并初始化使他们分别指向数组的首尾left = 0 right = len(height)-1
  • 计算容积min(height[left],height[right])*(right-left)
  • 比较最大容积和此时的容积,取最大值更新容积
  • 两个指针中所指向的高度较低的那个移动,(left右移,right左移)
  • 若left!=right,则重复进行步骤3,4,5
  • 返回最大容积
2.2 流程图

在这里插入图片描述

2.3 代码实现
class Solution:
    def maxArea(self, height: List[int]) -> int:
        # 1.排列组合问题
        #n个垂线,两两组合,共有n(n-1)/2种非重复结果
        ## 两垂线同x轴构成的容器容积大小为:min(height[i1],height[i2])*((i1-i2) if i1>i2 else i2-i1) 
        # 时间复杂度高
        # n = len(height)
        # max_V = 0

        # for i in range(n):
        #     for j in range(i+1,n):
        #         v = min(height[i],height[j])*((i-j) if i>j else j-i)
        #         if v>max_V:
        #             max_V = v

        #2.优化
        n = len(height)
        left = 0
        right = n-1
        max_V = 0

        while left!=right:
            v = min(height[left],height[right])*(right-left)
            if v>max_V:
                max_V = v
            if height[left] >= height[right]:
                right-=1
            else:
                left+=1
        
        return max_V

day5

1.罗马数字转整数(⭐️)

罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。

字符          数值
I             1
V             5
X             10
L             50
C             100
D             500
M             1000
例如, 罗马数字 2 写做 II ,即为两个并列的 1 。12 写做 XII ,即为 X + II 。 27 写做  XXVII, 即为 XX + V + II 。

通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况:

I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。 
C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。
给定一个罗马数字,将其转换成整数。
1.1 算法思路

看题可以发现存在IX这类组合字符,对这类字符的处理我们可以利用规则“通常情况下,罗马数字中小的数字在大的数字的右边。IX这类都属于特殊规则”

1.2 流程图
1.3 代码实现
class Solution:
    def romanToInt(self, s: str) -> int:
        dic2 = {'M':1000,'D':500,'C':100,'L':50,'X':10,'V':5,'I':1}
        
        n = len(s)

        ans = 0
        
        for i,c in enumerate(s):
            if i<n-1 and dic2[s[i+1]]>dic2[s[i]]:
                ans-=dic2[s[i]]
                continue
            ans+=dic2[s[i]]

        return ans
            

2.最长公共前缀(⭐️)

编写一个函数来查找字符串数组中的最长公共前缀。

如果不存在公共前缀,返回空字符串 ""。
2.1 算法思路

数组的遍历

2.2 流程图

在这里插入图片描述

2.3 代码实现
class Solution:
    def longestCommonPrefix(self, strs: List[str]) -> str:
        c = ''
        strs.sort(key = lambda i :len(i))
        print(strs)
        for i in range(len(strs[0])):
            c+=strs[0][i]
            #print(c)
            for s in strs:
                if s[i]!=c[-1]:
                    c = c[0:-1]
                    return c
            
        return c
                

3.三数之和(⭐️⭐️)

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。

请你返回所有和为 0 且不重复的三元组。

注意:答案中不可以包含重复的三元组。
3.1 算法思路
  • 对列表排序
  • 定义三个指针first,second,third
  • 枚举a,逐个遍历即可
  • 枚举b,从a后一位开始枚举
  • 枚举c,从数组尾部向前移动,移动至接近a+b+c>0的临界
3.2 流程图
3.3 代码实现
class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        nums.sort()#使待处理数组有序(升序)
        ans = []
        #first 指向三元组首个元素
        # 枚举a
        for first in range(len(nums)):
            # first每次进入三元组不重复
            if first>0 and nums[first]==nums[first-1]:
                continue
            #c+b = target
            target = -1*nums[first]
            #c从数组最右侧
            third = len(nums)-1
            
            #枚举b
            for second in range(first+1,len(nums)):
                # 保证同上次枚举的不重复
                if nums[second]==nums[second-1] and second > first+1:
                    continue
                
                # 枚举c
                while second<third and nums[second]+nums[third]>target:
                    third-=1
                #判断其退出循环的方式
                #两者值想同,但是a+b>-c.此时a,b定,c活动,但c再左移,就算是出现了符合a+b+c的三元组,也是重复的
                if second==third:
                    break
                
                if nums[second]+nums[third]==target:
                    ans.append([nums[first],nums[second],nums[third]])
        
        return ans

4. 最接近的三数之和(⭐️⭐️)

给你一个长度为 n 的整数数组 nums 和 一个目标值 target。请你从 nums 中选出三个整数,使它们的和与 target 最接近。

返回这三个数的和。

假定每组输入只存在恰好一个解
4.1算法思路

以数组A[1,2,3,4,5,6,7,8]为例,target = 7
在这里插入图片描述
我们需要从中选出与target 最近的值,因为涉及距离比较问题。
我们使用num1,num2,num3 的和sum与target的差的绝对值来表示三数与target的接近程度。
涉及到三数的非重复枚举,可参考上题的三数之和的思路,先排序,再枚举。
在这里插入图片描述

在枚举过程中需考虑几个情况:

  • (1)三数之和 = target:return target
  • (2)三数之和 > target: c左移
  • (3)三数之和 < target: b右移
4.2 代码
class Solution:
    def threeSumClosest(self, nums: List[int], target: int) -> int:
        nums.sort()
        n = len(nums)
        best = 10**7
        
        # 根据差值的绝对值来更新答案
        def update(cur):
            nonlocal best
            if abs(cur - target) < abs(best - target):
                best = cur
        
        # 枚举 a
        for i in range(n):
            # 保证和上一次枚举的元素不相等
            if i > 0 and nums[i] == nums[i - 1]:
                continue
            # 使用双指针枚举 b 和 c
            j, k = i + 1, n - 1
            while j < k:
                s = nums[i] + nums[j] + nums[k]
                # 如果和为 target 直接返回答案
                if s == target:
                    return target
                update(s)
                if s > target:
                    # 如果和大于 target,移动 c 对应的指针
                    k0 = k - 1
                    # 移动到下一个不相等的元素
                    while j < k0 and nums[k0] == nums[k]:
                        k0 -= 1
                    k = k0
                else:
                    # 如果和小于 target,移动 b 对应的指针
                    j0 = j + 1
                    # 移动到下一个不相等的元素
                    while j0 < k and nums[j0] == nums[j]:
                        j0 += 1
                    j = j0

        return best

day6

1.电话号码的字符组合

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
算法思路

回溯法

流程图
代码
class Solution:
    def letterCombinations(self, digits: str) -> List[str]:
        if not digits:
            return list()
        
        phoneMap = {
            "2": "abc",
            "3": "def",
            "4": "ghi",
            "5": "jkl",
            "6": "mno",
            "7": "pqrs",
            "8": "tuv",
            "9": "wxyz",
        }

        def backtrack(index: int):
            if index == len(digits):
                combinations.append("".join(combination))
            else:
                digit = digits[index]
                for letter in phoneMap[digit]:
                    combination.append(letter)
                    backtrack(index + 1)
                    combination.pop()

        combination = list()
        combinations = list()
        backtrack(0)
        return combinations

2. 四数之和

给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):

0 <= a, b, c, d < n
a、b、c 和 d 互不相同
nums[a] + nums[b] + nums[c] + nums[d] == target
你可以按 任意顺序 返回答案 
代码
class Solution:
    def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
        nums.sort()
        n = len(nums)

        res = []

        if n<4 :
            return res

        #枚举a
        for a in range(n-3):
            if a>0 and nums[a]==nums[a-1]:
                continue
            #枚举b
            for b in range(a+1,n-2):
                if b>a+1 and nums[b]==nums[b-1]:
                    continue
                # c,d 初始化
                c = b+1
                d = n-1
                while c<d :
                    # 更新c,d
                    if nums[a]+nums[b]+nums[c]+nums[d]>target:
                        d-=1
                    elif nums[a]+nums[b]+nums[c]+nums[d]<target:
                        c+=1
                    else:
                        res.append([nums[a],nums[b],nums[c],nums[d]])
                        while c<d and nums[c]==nums[c+1]:
                            c+=1
                        c+=1
                        while c<d and nums[d]==nums[d-1]:
                            d-=1
                        d-=1

        return res           

3.删除链表的倒数第 N 个结点(⭐️⭐️)

给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
3.1 算法思路

设立两个指针first,second
first初始化为head的头节点
同步后移两个指针,直至指针j移动至最后一个节点时,指针i指向该链表倒数第N个节点
删除该节点然后返回链表头节点

3.2 代码
class Solution:
    def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
        dummy = ListNode(0, head)
        first = head
        second = dummy
        for i in range(n):
            first = first.next

        while first:
            first = first.next
            second = second.next
        
        second.next = second.next.next
        return dummy.next

4.有效的括号

给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。

有效字符串需满足:

左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
每个右括号都有一个对应的相同类型的左括号。
4.1 算法思路

声明一个辅助字典(hash表)dic = {
‘]’:‘[’,
‘}’:‘{’,
‘)’:‘(’
}
以及一个辅助栈stack = []
1.考虑到输入只有这三种括号类型的字符
故可以知道,当字符串长度为奇数时,括号不可能匹配上
2.我们使用上面的辅助栈来匹配括号
在扫描字符串时遇到字符ch不在dic的key集合,即不是右括号的情况时,将其压入stack中。
若遇见右括号则需判断该右括号的对应左括号是否在stack的倒数第一个位置中,若在则弹出,否则返回 False

4.2
4.3 代码实现
class Solution:
    def isValid(self, s: str) -> bool:
        if len(s) % 2 == 1:
            return False
        
        pairs = {
            ")": "(",
            "]": "[",
            "}": "{",
        }
        stack = list()
        for ch in s:
            if ch in pairs:
                if not stack or stack[-1] != pairs[ch]:
                    return False
                stack.pop()
            else:
                stack.append(ch)
        
        return not stack

day7

1.两数之和

1.1算法思路
1.2
1.3 代码实现
class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        # 排序
        res = []
        for i,num in enumerate(nums):
            res.append((num,i))
        res = sorted(res,key = lambda x:(x[0]))
        #
        i = 0
        j = len(nums)-1
        while i<j:
            if res[i][0]+res[j][0] == target:
                return [res[i][1],res[j][1]]
            elif res[i][0]+res[j][0] < target:
                i+=1
            else:
                j-=1
        
        return []

2.

3.

4.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值