坚持刷题的第三周

紧接上一周的活动哦,大家可以看看我之前发的博客。

活动地址:https://blink.csdn.net/details/1253757?spm=1001.2014.3001.5501

2021-10-25

题目

1.最大子序和

坚持刷题的第三周_第1张图片

2.搜索插入位置

坚持刷题的第三周_第2张图片

3.检测大写字母

坚持刷题的第三周_第3张图片

4.最后一个单词长度

坚持刷题的第三周_第4张图片

5.搜索二维矩阵

坚持刷题的第三周_第5张图片

6.有效的字母异位词

坚持刷题的第三周_第6张图片

题解

1.最大子序和

本题是一个一维dp问题,我们可以用双指针,或者分治法来解本题。

首先我们先定义一个最大值和当前最大值,然后经行循环相加,并经行判断,如果当前数和下一位数相加的话大于下一位数,我们就把指针向右继续移动,在当前最大值和下一个数进行对比,谁大就把谁赋值给最大值,反之小于的话,我么就直接从下一个数从头开始相加,直到找到最大值!!!

2.搜索插入位置

在python本题思路比较好写,我们可以先把数组里面的数和插入数进行对比,如果数组中有第一个数大于插入值然后直接返回该数的下标,如果数组中都没有大于插入数的我们就直接可以返回原数组的长度。

3.检测大写字母

这个题开始我准备用双指针来写的,但是最后几个例子总是出错,然后我就直接看了题解,题解就职直接用的就是函数,我觉得这个就没啥意思了,我就先不说这个题的题解了。

4.最后一个单词长度

此题和我之前做的返回字符串的中的单词数很类似,我们可以把这个字符串里面的所有单词给添加到一个列表里面去,最后返回列表里面的最后一个单词的长度,如何添加单词大家可以看我上面的那个题的题解哦!!!

5.搜索二维矩阵

这个题在python中其实能卡一个bug----用 in 一下子就出来了,时间复杂度也是n。

但是我们刷算法的目的是什么?就是为了最优的解决这个问题,让它的效率最大化!!

所以我们不应该取巧的。

这个题主要的思路就是以右上角开始,如果目标变量比右上角的数小,就向左移一列,如果目标标量比右上角的数大就下一移动到下一行的数组中,由此来判断,最后是否能够在这个二维数组里面找到这个目标变量!

两者的复杂度:

坚持刷题的第三周_第7张图片

6.有效的字母异位词

 t是 ss 的异位词等价于「两个字符串排序后相等」。因此我们可以对字符串 ss 和 tt 分别排序,看排序后的字符串是否相等即可判断。此外,如果 ss 和 tt 的长度不同,tt 必然不是 ss 的异位词。

代码

1.最大子序和

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        temp = nums[0]
        max1 = temp
        for i in range(1,len(nums)):
            if temp + nums[i]> nums[i]:
                max1 = max(max1,temp+nums[i])
                temp = temp + nums[i]
            else :
                max1= max(max1,nums[i],temp,temp +nums[i])
                temp = nums[i]
        return max1

2.搜索插入位置

class Solution:
    def searchInsert(self, nums: List[int], target: int) -> int:
        
        for index,i in enumerate(nums):
            if i >= target:
                return index
        else: return len(nums)

3.检测大写字母

class Solution:
    def detectCapitalUse(self, word: str) -> bool:
         return word.islower() or word.isupper() or word.istitle()
        

4.最后一个单词长度

class Solution:
    def lengthOfLastWord(self, s: str) -> int:
        list1 = []
        string = ''
        for i in s:
            if i!=' ':
                string = string + i
            elif i == ' ':
                if string != '':
                    list1.append(string)
                    string = ''
        if string != '':
            list1.append(string)
        return len(list1[-1])

5.搜索二维矩阵

class Solution:
    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
        x = 0
        y = len(matrix[0])-1
        
        while x<=len(matrix) -1 and y>=0:
            t = matrix[x][y]
            if target >t:
                x += 1
            elif target < t:
                y -= 1
            else : return True
        return False

6.有效的字母异位词

class Solution(object):
    def isAnagram(self, s, t):
        """
        :type s: str
        :type t: str
        :rtype: bool
        """
        dic1={c:s.count(c) for c in set(s)}
        dic2={d:t.count(d) for d in set(t)}
        if dic1==dic2:
            return True
        else:return False

总结

今天就是第三周,真的没想到能坚持这么久,而且我发现我现在也慢慢把刷题当作了一种习惯,每天都必要刷几题,我也很喜欢刷题带来的成就感,能让我得到满足感,人生何尝不是如此在一方面做成功了,也会得到一定的成就感和满足感!!!

加油!!!肝就完事!!!

每日一语!!!

  • 耐心之树,结黄金之果。

2121-10-26

题目

1.下一个最大数

给你两个 没有重复元素 的数组 nums1 和 nums2 ,其中nums1 是 nums2 的子集。

请你找出 nums1 中每个元素在 nums2 中的下一个比其大的值。

nums1 中数字 x 的下一个更大元素是指 x 在 nums2 中对应位置的右边的第一个比 x 大的元素。如果不存在,对应位置输出 -1 。

输入: nums1 = [4,1,2], nums2 = [1,3,4,2].
输出: [-1,3,-1]
解释:
    对于 num1 中的数字 4 ,你无法在第二个数组中找到下一个更大的数字,因此输出 -1 。
    对于 num1 中的数字 1 ,第二个数组中数字1右边的下一个较大数字是 3 。
    对于 num1 中的数字 2 ,第二个数组中没有下一个更大的数字,因此输出 -1 。

输入: nums1 = [2,4], nums2 = [1,2,3,4].
输出: [3,-1]
解释:
    对于 num1 中的数字 2 ,第二个数组中的下一个较大数字是 3 。
    对于 num1 中的数字 4 ,第二个数组中没有下一个更大的数字,因此输出 -1 。

提示:

1 <= nums1.length <= nums2.length <= 1000
0 <= nums1[i], nums2[i] <= 104
nums1和nums2中所有整数 互不相同
nums1 中的所有整数同样出现在 nums2 中

2.左转字符串

字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。

示例 1:

输入: s = "abcdefg", k = 2
输出: "cdefgab"
示例 2:

输入: s = "lrloseumgh", k = 6
输出: "umghlrlose"
 

限制:

1 <= k < s.length <= 10000

3.最长公共前缀 

坚持刷题的第三周_第8张图片

4.整数反转 

坚持刷题的第三周_第9张图片

 5.字符串中的唯一的一个字符

坚持刷题的第三周_第10张图片

题解

1.下一个最大数

本题可以有两种解法:

1.就是最原始的暴力解法,两个循环就可以出来了,我就不多讲这个了,这个代码我倒是没有提交,我写在本子上面了,我给大家看看。

2.

 第二种就是用哈希表和栈的方法:

因为题中说明是不重复的数组,所以我们直接把nums2入栈,且判断栈尾元素是要小于栈里面的元素,否则出栈,并把对应的数字放入哈希表中,最后返回列表!!!

2.左转字符串

这个在python友谊中方法很简单很简单,直接用下标替换就可以,如果学过py的直接看代码就可以看懂了,因为今天有点累了,我就不说太多了!!! 

3.最长公共前缀 

 本题是使用一个移动的变化滑块来写这个题,我们来对每一个做前缀做一个判断,如果符合就直接返回,如果不符合就返已经匹配滑块里面的东西。

4.整数反转 

时间问题欠着

 5.字符串中的唯一的一个字符

同上

代码

 1.下一个最大数

class Solution:
    def nextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]:
        stack = []
        res = {}
        for num in reversed(nums2):
            while stack and stack[-1]

2.左转字符串 

class Solution:
    def reverseLeftWords(self, s: str, n: int) -> str:
        l = [ i for i in s]
        l[:] = l[n : ] + l[ : n]
        string = ''
        for i in l :
            string  = string +i
        return string

3.最长公共前缀  


class Solution:
    def longestCommonPrefix(self, strs) :
        if len(strs) == 0: return ""
        pre = strs[0]
        strs = strs[1:]

        for i in range(len(strs)):
            count = 0
            if len(pre) < len(strs[i]):
                length = len(pre)
            else:
                length = len(strs[i])
            for j in range(length):
                if strs[i][j] == pre[j]:
                    count += 1
                else:
                    break
            pre = pre[:count]

        return pre

4.整数反转

class Solution(object):
    def reverse(self, x):
        """
        :type x: int
        :rtype: int
        """
        sum = 0
        if x<=0:
                for i,j in enumerate(str(abs(x))):
                 sum += int(j)*(10**i)
                if -2**31<-sum<=2**31-1:
                 return -sum
                else:
                   return 0
        else:
                for i,j in enumerate(str(x)):
                 sum += int(j)*(10**i)
                if -2**31

 5.字符串中的唯一的一个字符 

class Solution(object):
    def firstUniqChar(self, s):
        """
        :type s: str
        :rtype: int
        """
        hash_map = dict()
        for index, value in enumerate(s):
            if value in hash_map:
                hash_map[value] += 1
            else:
                hash_map[value] = 1
        for index, value in enumerate(s):
            if hash_map[value] == 1:
                return index
        return -1

总结

欠着。。。。。。 


2021-10-27 

题目

1.左转字符串||

字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。

示例 1:

输入: s = "abcdefg", k = 2
输出: "cdefgab"
示例 2:

输入: s = "lrloseumgh", k = 6
输出: "umghlrlose"
 

限制:

1 <= k < s.length <= 10000

2.数组形式的整数加法

对于非负整数 X 而言,X 的数组形式是每位数字按从左到右的顺序形成的数组。例如,如果 X = 1231,那么其数组形式为 [1,2,3,1]。

给定非负整数 X 的数组形式 A,返回整数 X+K 的数组形式。

示例 1:

输入:A = [1,2,0,0], K = 34
输出:[1,2,3,4]
解释:1200 + 34 = 1234
示例 2:

输入:A = [2,7,4], K = 181
输出:[4,5,5]
解释:274 + 181 = 455
示例 3:

输入:A = [2,1,5], K = 806
输出:[1,0,2,1]
解释:215 + 806 = 1021
示例 4:

输入:A = [9,9,9,9,9,9,9,9,9,9], K = 1
输出:[1,0,0,0,0,0,0,0,0,0,0]
解释:9999999999 + 1 = 10000000000
 

提示:

1 <= A.length <= 10000
0 <= A[i] <= 9
0 <= K <= 10000
如果 A.length > 1,那么 A[0] != 0

3.反转字符串 II

给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。

如果剩余字符少于 k 个,则将剩余字符全部反转。
如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。
 

示例 1:

输入:s = "abcdefg", k = 2
输出:"bacdfeg"
示例 2:

输入:s = "abcd", k = 2
输出:"bacd"
 

提示:

1 <= s.length <= 104
s 仅由小写英文组成
1 <= k <= 104

4.有效字母的异位

坚持刷题的第三周_第11张图片

5.验证回文串

坚持刷题的第三周_第12张图片

题解

1.左转字符串||

我们可以直到字符串其实也是一种数组的形式,我们呢可以用字符串的直接切片来写这个题,所以我对昨天的代码进行了一个简单的优化,昨天好像是超越20多,今天是超越了80,内存也提高了很多!!!

接下来我们可以直接看代码!!!

2.数组形式的整数加法

本题最简单最方便的方法就是直接把数组里面的数给转化为整数,然后在相加k,再把相加后的结果给放到数组中,这样就直接返回接过来,但是这个效率是十分低的。

第二种方法就是使用模拟法,我们先把k转化为数组然后对位相加,相加后

坚持刷题的第三周_第13张图片

这个也是字符串相乘的一个基础解题法!!!

3.反转字符串 II

本题在python中我觉得有一个很方便的一个办法,就是range中的第三个参数,每次循环多少个步长,本题可知每次走2k个步长就可以直接使用这个range的步长参数,走2k让前k个数反转。

4.有效字母的异位

这题我有点投机取巧,用了python中的count这个函数,我建议大家还是很少用就少用,自己去写一个计数方法。

5.验证回文串

 这个就是一个简单的双指针,我就不多解释了,直接上代码!!

代码

1.左转字符串||

class Solution:
    def reverseLeftWords(self, s: str, n: int) -> str:
        string = s[n:]+s[:n]
        return string
#本代码在python实现是非常简单的

2.数组形式的整数加法

class Solution:
    def addToArrayForm(self, num: List[int], k: int) -> List[int]:
        res  = 0
        for i in range(len(num)):
            res = res+(10**i)*num[len(num)-i-1]
        return [int(i) for i in str(res+k)]

3.反转字符串 II

class Solution:
    def reverseStr(self, s: str, k: int) -> str:
        ss = [i for i in s]
        n=len(s)
        for i in range(0,n,2*k):
            ss[i:i+k]=ss[i:i+k][::-1]
        return "".join(ss)
 

4.有效字母的异位

class Solution(object):
    def isAnagram(self, s, t):
        """
        :type s: str
        :type t: str
        :rtype: bool
        """
        dic1={c:s.count(c) for c in set(s)}
        dic2={d:t.count(d) for d in set(t)}
        if dic1==dic2:
            return True
        else:return False

5.验证回文串

class Solution(object):
    def isPalindrome(self, s):
        """
        :type s: str
        :rtype: bool
        """
        if 1<=len(s) <=2*10**5:
            c = ''    
            for i in s:
                if i.isalpha():
                    c += i.lower()
                elif i.isalnum():
                    c += i
            n = len(c)//2
            for i in range(n):
                if c[i] != c[len(c)-i-1]:
                    return False
            else:
                    return True

总结

欠着!!!!


2021-10-28

题目

1.2的幂

给你一个整数 n,请你判断该整数是否是 2 的幂次方。如果是,返回 true ;否则,返回 false 。

如果存在一个整数 x 使得 n == 2x ,则认为 n 是 2 的幂次方。

示例 1:

输入:n = 1
输出:true
解释:20 = 1
示例 2:

输入:n = 16
输出:true
解释:24 = 16
示例 3:

输入:n = 3
输出:false
示例 4:

输入:n = 4
输出:true
示例 5:

输入:n = 5
输出:false
 

提示:

-231 <= n <= 231 - 1

2.全排列 

给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。

示例 1:

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

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

输入:nums = [1]
输出:[[1]]
 

提示:

1 <= nums.length <= 6
-10 <= nums[i] <= 10
nums 中的所有整数 互不相同

 3.全排列|| 

给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列。

示例 1:

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

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

  4.组合两个表

坚持刷题的第三周_第14张图片

坚持刷题的第三周_第15张图片

 5.重新排序得到 2 的幂

给定正整数 N ,我们按任何顺序(包括原始顺序)将数字重新排序,注意其前导数字不能为零。

如果我们可以通过上述方式得到 2 的幂,返回 true;否则,返回 false。

示例 1:

输入:1
输出:true
示例 2:

输入:10
输出:false
示例 3:

输入:16
输出:true
示例 4:

输入:24
输出:false
示例 5:

输入:46
输出:true

题解

1.2的幂

这个题我们直接可以用与运算来写出如果n&(n-1)==0返回true就证明这是是2的幂数,明天我可能就会更新一些运算符的使用,有一些运算符在写踢的时候是很方便的,还要注意一点这个是要大于0的!

2.全排列 

本题就是一个简单的回溯加剪枝,我们在回溯的条件上添加一个剪枝,判断每一个排序中是否已经有了该元素,如果有了就直接跳过此次循环,每次回溯的终止条件就是子元素的长度是否等于给定的长度,我们来借鉴一下官方的图:

坚持刷题的第三周_第16张图片

看图是能比较好理解的,如果大家懂了这个图的原理,还有回溯的原理就可以直接下手本题了!! 

 3.全排列|| 

 本题是上一题的一个进阶问题,本题多出了两个条件,给的数组里面的元素是可以重复的,但是排序的结果是不能重复的。

我们还是用回溯加剪枝,我们还需要把每个重复的元素给经行一个标记,我们可以创建一个新的全为0等长的列表,然后判断如果有重复的,则对应新列表重复的下标转化为1,在回溯的时候判断,如果新列表的哪个下标为1就直接跳过此次循环,这样就去重了一些,然后回溯在进行排序。

 4.组合两个表 

本题考的就是两个表的如何合并,在MySQL中我们可以先用outer join合并这两个表,然后在在合并的表中进行查询,这个是一个基本的思路,我最后测试了一下效率不是很高但是没有什么问题。

5.重新排序得到 2 的幂 

本题是今天的每日一题,本题有一种解法就是用回溯加对2幂数经行判断,我最开始写的几道题就是为这个题做铺垫,但是呢我并没有用那种方法去写嘿嘿嘿嘿,我看到了一个新的思路。就是我们可以把2的31个幂数列举出来,然后在给这些幂函数转化为二进制的数,并放在列表中,我们也把目标数转化为二进制数放在列表中,然后经行a和b两个数组进行对比如果相等就返回true,反之返回false。

6.买股票的最佳时机

坚持刷题的第三周_第17张图片

代码

1.2的幂

class Solution:
    def isPowerOfTwo(self, n: int) -> bool:
        return n>0 and n&(n-1)== 0

2.全排列  

class Solution:
    def permute(self, nums: List[int]) -> List[List[int]]:
        res = []
        def trace (nums,path):
            if len(path) == len(nums):
                res.append(list(path))
                return
            for i in nums:
                if i in path:
                    continue
                path.append(i)
                trace(nums,path)
                path.pop()
        trace(nums,[])
        return res

 3.全排列||



    
    
    
class Solution:
    def permuteUnique(self, nums: List[int]) -> List[List[int]]:
        nums.sort()
        res = []
        check =[0 for i in range(len(nums))]
        def trace (nums,path,check):
            if len(path) == len(nums):
                    res.append(list(path))
                    return
            for i in range(len(nums)):
                if check[i] == 1:
                    continue
                if i>0 and nums[i]==nums[i-1] and check[i-1] ==0:
                    continue
                check[i]=1
                trace(nums,path+[nums[i]],
                      check)
                
                check[i]=0
        trace(nums,[],check)
        return res
    
    
    
    
    
    
class Solution1:
    def permuteUnique(self, nums: List[int]) -> List[List[int]]:
        nums.sort()
        res = []
        check = [0 for i in range(len(nums))]
        def backtrack(sol, nums, check):
            if len(sol) == len(nums):
                res.append(list(sol))
                return
        
            for i in range(len(nums)):
                if check[i] == 1:
                    continue
                if i > 0 and nums[i] == nums[i-1] and check[i-1] == 0:
                    continue
                check[i] = 1
                backtrack(sol+[nums[i]], nums, check)
                check[i] = 0
        backtrack([], nums, check)
        return res
    
    


        
    
            
            
            
            
            

 4.组合两个表


select FirstName, LastName, City, State
from Person left join Address
on Person.PersonId = Address.PersonId
;

 5.重新排序得到 2 的幂

class Solution:
    def reorderedPowerOf2(self, n: int) -> bool:
        def check(targ: int, num: int) -> bool:
            a = [0 for _ in range(10)]
            b = [0 for _ in range(10)]
            while targ:
                x = targ % 10 
                a[x] += 1
                targ //= 10
            while num:
                x = num % 10
                b[x] += 1
                num //= 10
            return a == b


        for i in range(31):
            targ = 2 ** i
            if check(targ, n) == True:
                return True
        return False

6.买卖股票的最佳时机 

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        n = len(prices)
        if n == 0: return 0 # 边界条件
        dp = [0] * n
        minprice = prices[0] 

        for i in range(1, n):
            minprice = min(minprice, prices[i])
            dp[i] = max(dp[i - 1], prices[i] - minprice)

        return dp[-1]

总结 

2021-10-29

 路径交叉

给你一个整数数组 distance 。

从 X-Y 平面上的点 (0,0) 开始,先向北移动 distance[0] 米,然后向西移动 distance[1] 米,向南移动 distance[2] 米,向东移动 distance[3] 米,持续移动。也就是说,每次移动后你的方位会发生逆时针变化。

判断你所经过的路径是否相交。如果相交,返回 true ;否则,返回 false 。

坚持刷题的第三周_第18张图片

坚持刷题的第三周_第19张图片

坚持刷题的第三周_第20张图片

题解

本题看似是一个hard的一个难度,但是如果我们弄懂了它的原理这个就是一个esay的题,本题难就难在这个题他是比较偏向数学分类较多一些,它分为好几种情况相交,我把这些相交的情况都给写在本子上了,大家可以看看!!!

草稿:

我上面如果画的不清楚大家也可以去看看官方的图,其实原理都是一样的!!! 

代码

class Solution:
    def isSelfCrossing(self, distance: List[int]) -> bool:
        n = len(distance)
        for i in range(3, n):
           
            if (distance[i - 1] <= distance[i - 3] 
                    and distance[i] >= distance[i - 2]):
                return True
            
            if (i >= 4 and distance[i - 1] == distance[i - 3]
                and distance[i - 2] <= distance[i] + distance[i - 4]):
                return True
           
            if (i >= 5 and distance[i - 2] >= distance[i - 4]
                and distance[i] >= distance[i - 2] - distance[i - 4]
                and distance[i - 3] >= distance[i - 5]
                and distance[i - 3] >= distance[i - 1]
                and distance[i - 3] <= distance[i - 5] + distance[i - 1]):
                return True
        return False

 括号生成

数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。

有效括号组合需满足:左括号必须以正确的顺序闭合。

示例 1:

输入:n = 3
输出:["((()))","(()())","(())()","()(())","()()()"]
示例 2:

输入:n = 1
输出:["()"]

题解

本题就是变了一个样子的回溯题,本题有几个剪枝的条件,第一:左括号剩的数要大于右括号。第二:左右括号都为0的时候才能结束。

然后我们对这个进行回溯剪枝,并把每一次生成的序列放在列表中,回溯结束则返回列表!

本题主要就是掌握回溯,如果回溯没有掌握好的话,大家可以去csdn上面找一些大佬们的介绍!

代码

class Solution:
    def generateParenthesis(self, n: int) -> List[str]:
        res =""
        chect =[]
        def trace(res,r,z,n):
            if r == n and z == n:
                chect.append(res)
                return
            if z < r:
                return 
            if z < n:
                trace(res+"(",r,z+1,n)
            if r

 组合

给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。

你可以按 任何顺序 返回答案。

示例 1:

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

输入:n = 1, k = 1
输出:[[1]]
 

提示:

1 <= n <= 20
1 <= k <= n

题解

本题也是非常经典的一个题,我最开始是把1到n所有的数给转化为列表然后在回溯,然后我就给他写在本子上了

坚持刷题的第三周_第21张图片

然后我发现我这个有点复杂了,所以我看了一些大佬们的题解,我觉得他们的是真简单 然后我就采用他们的方式来写的,

代码

class Solution:
    def combine(self, n: int, k: int) -> List[List[int]]:
        res = []
        def bracktrace(path,i):
            if len(path) == k:
                res.append(path)
                return
            for j in range(i,n+1) :
                bracktrace(path+[j],j+1)
        bracktrace([],1)
        return res

字符串转换整数 (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 。
返回整数作为最终结果。
注意:

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

坚持刷题的第三周_第22张图片

坚持刷题的第三周_第23张图片

 这个有很多方法,这个看起来很复杂,其实很简单,最麻烦的是你判断范围时候,你的代码会很多,不注意一些变量的使用导致错误。

我是用的re,也是有点取巧的成分。

class Solution(object):
    def myAtoi(self, s):
        """
        :type s: str
        :rtype: int
        """
        import re
        
        pattern = r"[\s]*[+-]?[\d]+"
        match = re.match(pattern, s)
        if match:
            res = int(match.group(0))
            if res > 2 ** 31 - 1:
                res = 2 ** 31 -1
            if res < - 2 ** 31:
                res = - 2 ** 31
        else:
            res = 0
        return res

 实现strStr()

 坚持刷题的第三周_第24张图片

 这个题我开始没有理解题意然后一直卡着,我就看了下面大佬们的解题思路,而且也学到了新的一种方法————滑块。这个方法做这个题是十分简单的,可能以后写项目的也会用这个办法,反正学到就是赚到,嘿嘿。话不多说,直接上代码。

class Solution(object):
    def strStr(self, haystack, needle):
        """
        :type haystack: str
        :type needle: str
        :rtype: int
        """
        if needle == '' or haystack == 0:
            return 0
        if len(haystack)>=len(needle):
            right = len(haystack)
            i = 0
            n = len(needle)
            while i


2021-10-30

 只出现一次的数字 III

给定一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。你可以按 任意顺序 返回答案。

进阶:你的算法应该具有线性时间复杂度。你能否仅使用常数空间复杂度来实现?

示例 1:

输入:nums = [1,2,1,3,2,5]
输出:[3,5]
解释:[5, 3] 也是有效的答案。
示例 2:

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

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

2 <= nums.length <= 3 * 104
-231 <= nums[i] <= 231 - 1
除两个只出现一次的整数外,nums 中的其他数字都出现两次

题解

本题就是用一个哈希表来简单的使用,把每个不同的元素都放在哈希表中,然后直接使用一个循环,循环nums数组里面的元素,如果多余的话直接加一就可以,最后返回等于的元素就是我们想要的元素。

代码

class Solution:
    def singleNumber(self, nums: List[int]) -> List[int]:
        dit = {}
        res =[]
        for i in set(nums):
            dit[i] = 0
        for i in nums:
            dit[i]+=1
        for i in dit:
            if dit[i] == 1:
                res.append(i)
        return res

坚持刷题的第三周_第25张图片


增量元素之间的最大差值

给你一个下标从 0 开始的整数数组 nums ,该数组的大小为 n ,请你计算 nums[j] - nums[i] 能求得的 最大差值 ,其中 0 <= i < j < n 且 nums[i] < nums[j] 。

返回 最大差值 。如果不存在满足要求的 i 和 j ,返回 -1 。

示例 1:

输入:nums = [7,1,5,4]
输出:4
解释:
最大差值出现在 i = 1 且 j = 2 时,nums[j] - nums[i] = 5 - 1 = 4 。
注意,尽管 i = 1 且 j = 0 时 ,nums[j] - nums[i] = 7 - 1 = 6 > 4 ,但 i > j 不满足题面要求,所以 6 不是有效的答案。
示例 2:

输入:nums = [9,4,3,2]
输出:-1
解释:
不存在同时满足 i < j 和 nums[i] < nums[j] 这两个条件的 i, j 组合。
示例 3:

输入:nums = [1,5,2,10]
输出:9
解释:
最大差值出现在 i = 0 且 j = 3 时,nums[j] - nums[i] = 10 - 1 = 9 。

题解

本题最核心的就是i

代码

class Solution:
    def maximumDifference(self, nums: List[int]) -> int:
        ans = -1
        for i in range(1, len(nums)):
            ans = max(ans, nums[i] -min(nums[0:i]))
        return ans if ans > 0 else -1


 网格游戏

给你一个下标从 0 开始的二维数组 grid ,数组大小为 2 x n ,其中 grid[r][c] 表示矩阵中 (r, c) 位置上的点数。现在有两个机器人正在矩阵上参与一场游戏。

两个机器人初始位置都是 (0, 0) ,目标位置是 (1, n-1) 。每个机器人只会 向右 ((r, c) 到 (r, c + 1)) 或 向下 ((r, c) 到 (r + 1, c)) 。

游戏开始,第一个 机器人从 (0, 0) 移动到 (1, n-1) ,并收集路径上单元格的全部点数。对于路径上所有单元格 (r, c) ,途经后 grid[r][c] 会重置为 0 。然后,第二个 机器人从 (0, 0) 移动到 (1, n-1) ,同样收集路径上单元的全部点数。注意,它们的路径可能会存在相交的部分。

第一个 机器人想要打击竞争对手,使 第二个 机器人收集到的点数 最小化 。与此相对,第二个 机器人想要 最大化 自己收集到的点数。两个机器人都发挥出自己的 最佳水平 的前提下,返回 第二个 机器人收集到的 点数 。

示例 1:

输入:grid = [[2,5,4],[1,5,1]]
输出:4
解释:第一个机器人的最佳路径如红色所示,第二个机器人的最佳路径如蓝色所示。
第一个机器人访问过的单元格将会重置为 0 。
第二个机器人将会收集到 0 + 0 + 4 + 0 = 4 个点。
示例 2:


输入:grid = [[3,3,1],[8,5,2]]
输出:4
解释:第一个机器人的最佳路径如红色所示,第二个机器人的最佳路径如蓝色所示。 
第一个机器人访问过的单元格将会重置为 0 。
第二个机器人将会收集到 0 + 3 + 1 + 0 = 4 个点。
示例 3:


输入:grid = [[1,3,1,15],[1,3,3,1]]
输出:7
解释:第一个机器人的最佳路径如红色所示,第二个机器人的最佳路径如蓝色所示。
第一个机器人访问过的单元格将会重置为 0 。
第二个机器人将会收集到 0 + 1 + 3 + 3 + 0 = 7 个点。
 

提示:

grid.length == 2
n == grid[r].length
1 <= n <= 5 * 104
1 <= grid[r][c] <= 105

题解

本题建议参考官方题解,我这个我也是半懂半不懂得。

代码

class Solution:
    def gridGame(self, grid: List[List[int]]) -> int:
        pre,suf = [0],[0]
        n = len(grid[0])
        for i in range(n):
            pre.append(pre[-1] + grid[1][i])
        for i in range(n - 1,-1,-1):
            suf.append(suf[-1] + grid[0][i])
        suf.reverse()
        ans = float('inf')
     
        for i in range(n):
            #左侧剩余分数
            lleft = pre[i]
            # 右侧剩余分数
            rleft = suf[i + 1]
            ans = min(ans,max(lleft,rleft))
        return ans

题目

题解

代码

题目

题解

代码


2021-10-31

 最长递增子序列

给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。

子序列是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。

 
示例 1:

输入:nums = [10,9,2,5,3,7,101,18]
输出:4
解释:最长递增子序列是 [2,3,7,101],因此长度为 4 。
示例 2:

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

输入:nums = [7,7,7,7,7,7,7]
输出:1

题解

因为今天学了基础的dp所以我就拿这个最经典的题来练练手,我们直接开始这个题解正题吧。

本题可以有很多种解法,贪心加二分,dp等,我是用的dp,我们可以先写一个递归,终止条件就是循环达到最后一个元素就返回,在递归里面判断是否有后面的数大于前面的数,有的话就直接加一,然后返回最大的那个长度。

本题还有数学归纳法,我直接把两种算法代码发在下面。

代码

1.dp

class Solution:
    def lengthOfLIS(self, nums: List[int]) -> int:
        meno = {}
        def l(nums,i):
            if i in meno:
                return meno[i]
            if i == len(nums) -1 :
                return 1
            max_1 = 1
            for j in range(i+1,len(nums)):
                if nums[j]>nums[i]:
                    max_1 = max(max_1,l(nums,j)+1)
            meno[i] = max_1
            return max_1
        return max( l(nums,i)for i in range(len(nums)))

2.数学归纳法

class Solution:
    def lengthOfLIS(self, nums: List[int]) -> int:
            l = [1]*len(nums)
            for i in reversed(range(len(nums))):
                for j in range(i,len(nums)):
                    if nums[j]>nums[i]:
                        l[i] = max(l[i],l[j]+1)
            return max(l)

 键盘行

给你一个字符串数组 words ,只返回可以使用在 美式键盘 同一行的字母打印出来的单词。键盘如下图所示。

美式键盘 中:

第一行由字符 "qwertyuiop" 组成。
第二行由字符 "asdfghjkl" 组成。
第三行由字符 "zxcvbnm" 组成。


 

示例 1:

输入:words = ["Hello","Alaska","Dad","Peace"]
输出:["Alaska","Dad"]
示例 2:

输入:words = ["omk"]
输出:[]
示例 3:

输入:words = ["adsdf","sfd"]
输出:["adsdf","sfd"]
 

提示:

1 <= words.length <= 20
1 <= words[i].length <= 100
words[i] 由英文字母(小写和大写字母)组成

题解

本题就是用all放来来判断一个单词是否属于键盘三行里面的算法,我们可以,本题过于简单,大家可以直接看代码就懂了。

代码

class Solution:
    def findWords(self, words: List[str]) -> List[str]:
        res = []
        s1 = "qwertyuiop"
        s2 = "asdfghjkl"
        s3 = "zxcvbnm" 
        for i in words:
            if all(x.lower() in s1 for x in i) or all(x.lower() in s2 for x in i) or all(x.lower() in s3 for x in i):
                res.append(i)
        return res

递增子序列

给你一个整数数组 nums ,找出并返回所有该数组中不同的递增子序列,递增子序列中 至少有两个元素 。你可以按 任意顺序 返回答案。

数组中可能含有重复元素,如出现两个整数相等,也可以视作递增序列的一种特殊情况。

示例 1:

输入:nums = [4,6,7,7]
输出:[[4,6],[4,6,7],[4,6,7,7],[4,7],[4,7,7],[6,7],[6,7,7],[7,7]]
示例 2:

输入:nums = [4,4,3,2,1]
输出:[[4,4]]
 

提示:

1 <= nums.length <= 15
-100 <= nums[i] <= 100

题解

本题使用dp加剪枝来解,我们可以定义一个dfs然后传参,传入nums和一个需要添加子序列的数组,添加条件是我们判断子序列大于等于2的时候。然后我们开始进行剪枝,首先创建一个集合,然后把每个子序列放在集合里面用来判断是否有重复的,如果有就跳过此次循环,没有就添加,然后在进行递归。直到递归结束。

代码

 
  
  1. class Solution:

  2. def findSubsequences(self, nums: List[int]) -> List[List[int]]:

  3. res = []

  4. def dfs(nums,path):

  5. if len(path) > 1:

  6. res.append(path)

  7. x = set()

  8. for index ,i in enumerate(nums):

  9. if i in x:

  10. continue

  11. if not path or i >= path[-1]:

  12. x.add(i)

  13. dfs(nums[index+1:],path+[i])

  14. dfs(nums,[])

 题目

题解

代码

题目

题解

代码

你可能感兴趣的:(数据结构,算法,基础,leetcode,算法,职场和发展)