LeetCode 每日一题 2023/3/27-2023/4/2

记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步


目录

      • 3/27 1638. 统计只差一个字符的子串数目
      • 3/28 1092. 最短公共超序列
      • 3/29 1641. 统计字典序元音字符串的数目
      • 3/30 1637. 两点之间不包含任何点的最宽垂直区域
      • 3/31 2367. 算术三元组的数目
      • 4/1 831. 隐藏个人信息
      • 4/2 1039. 多边形三角剖分的最低得分


3/27 1638. 统计只差一个字符的子串数目

遍历s,t每个起始位置 遍历长度k
判断两个子串差别字符diff是否为1

def countSubstrings(s, t):
    """
    :type s: str
    :type t: str
    :rtype: int
    """
    ans = 0
    for i in range(len(s)):
        for j in range(len(t)):
            diff = 0
            k = 0
            while i+k<len(s) and j+k<len(t):
                if s[i+k]!=t[j+k]:
                    diff +=1
                if diff==1:
                    ans +=1
                elif diff>1:
                    break
                k+=1
    return ans




3/28 1092. 最短公共超序列

将两个字符串直接相连 就是一个公共超序列 但是并不是最短的
为了超序列最短 我们要尽可能去除相同的序列
及求最长公共子序列LCS
使用动态规划dp[i][j]来代表str1[:i],str2[:j]的LCS长度
n,m = len(str1),len(str2)
那么最短公共超序列长度为n+m-dp[n][m]
下一步是还原处最长公共子序列
从后往前倒退 记录每一个关键节点在loc
从前往后遍历关键节点 将两个关键节点之间非关键的字符加入答案中即可
例如:
str1=“zabcz”
str2=“zdefz”
关键节点为(0,0),(4,4)
对于str1非关键位置为[1,3]将这部分加入
同样str2也是[1,3] 最后可以得到zabcdefz

def shortestCommonSupersequence(str1, str2):
    """
    :type str1: str
    :type str2: str
    :rtype: str
    """
    n,m = len(str1),len(str2)
    dp = [[0]*(m+1) for _ in range(n+1)]
    for i in range(1,n+1):
        for j in range(1,m+1):
            if str1[i-1]==str2[j-1]:
                dp[i][j] =dp[i-1][j-1]+1
            else:
                dp[i][j] = max(dp[i-1][j],dp[i][j-1])
    li,lj = n,m
    loc = []
    while li>0:
        if str1[li-1]==str2[lj-1]:
            loc.append([li-1,lj-1])
            li-=1
            lj-=1
        else:
            if dp[li-1][lj]==dp[li][lj]:
                li-=1
            else:
                lj-=1
    ans =""
    li,lj = -1,-1
   
    for i,j in loc[::-1]:
        if li+1<i:
            ans += str1[li+1:i]
        if lj+1<j:
            ans+= str2[lj+1:j]
        ans += str1[i]
        li,lj = i,j
    if li+1<n:
        ans += str1[li+1:]
    if lj+1<m:
        ans += str2[lj+1:]
    return ans



3/29 1641. 统计字典序元音字符串的数目

a,e,i,o,u标记为4,3,2,1,0
及前面的数值不能小于后面的数值
递归(cur,num) cur为当前可以选的最大值 num为还需要多少个数

def countVowelStrings(n):
    """
    :type n: int
    :rtype: int
    """
    mem={}
    def check(cur,num):
        ans = 0
        if num==0:
            return 1
        if (cur,num) in mem:
            return mem[(cur,num)]
        for v in range(cur+1):
            ans += check(v,num-1)
        mem[(cur,num)] = ans
        return ans
    return check(4,n)
            



3/30 1637. 两点之间不包含任何点的最宽垂直区域

只需要考虑横坐标位置
去重从小到大排序 寻找相邻点的最大值

def maxWidthOfVerticalArea(points):
    """
    :type points: List[List[int]]
    :rtype: int
    """
    l = list(set([p[0] for p in points]))
    l.sort()
    ans = 0
    for i in range(1,len(l)):
        ans = max(ans,l[i]-l[i-1])
    return ans



3/31 2367. 算术三元组的数目

确定第一个数 i 判断nums[i]+diff,nums[i]+2*diff是否在数组中

def arithmeticTriplets(nums, diff):
    """
    :type nums: List[int]
    :type diff: int
    :rtype: int
    """
    s = set(nums)
    n = len(nums)
    ans =0
    for i in range(n-2):
        if nums[i]+diff in s and nums[i]+2*diff in s:
            ans +=1
    return ans



4/1 831. 隐藏个人信息

先判断是否为邮箱
按邮箱处理方式处理邮箱
若是电话号码 则提取有多少数字 按照规则处理

def maskPII(s):
    """
    :type s: str
    :rtype: str
    """
    loc = s.find('@')
    if loc>=0:
        return (s[0]+"*"*5+s[loc-1:]).lower()
    s = "".join(i for i in s if i.isdigit())
    if len(s)==10:
        return "***-***-"+s[-4:]
    else:
        return "+"+"*"*(len(s)-10)+"-***-***-"+s[-4:]



4/2 1039. 多边形三角剖分的最低得分

假设dp[i][j]为顶点i…j的凸j-i+1边型的最低分
动态规划 遍历其中可能的k值
将dp[i][j]可分为
dp[i][k] i,k,j三角形 dp[k][j]

def minScoreTriangulation(values):
    """
    :type values: List[int]
    :rtype: int
    """
    n = len(values)
    mem={}
    def dp(i,j):
        if (i,j) in mem:
            return mem[(i,j)]
        if i+2>j:
            return 0
        if i+2==j:
            return values[i]*values[i+1]*values[j]
        ans =min((values[i] * values[k] * values[j] + dp(i, k) + dp(k, j)) for k in range(i + 1, j))
        mem[(i,j)] = ans
        return ans
    return dp(0,n-1)



你可能感兴趣的:(Exercise,leetcode,算法)