leetcode 1~10 学习经历

news2024/12/27 12:09:18

LeetCode 习题 1 - 10

  • 1. 两数之和
  • 2. 两数相加
  • 3. 无重复字符的最长子串
  • 4. 寻找两个正序数组的中位数
  • 5. 最长回文子串
  • 6. N 字形变换
  • 7. 整数反转
  • 8. 字符串转换整数 (atoi)
  • 9. 回文数
  • 10. 正则表达式匹配


1. 两数之和

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。

示例 1:
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
示例 2:
输入:nums = [3,2,4], target = 6
输出:[1,2]
示例 3:
输入:nums = [3,3], target = 6
输出:[0,1]

提示:
2 <= nums.length <= 104
-109 <= nums[i] <= 109
-109 <= target <= 109
只会存在一个有效答案

进阶:你可以想出一个时间复杂度小于 O(n2) 的算法吗?
通过次数4,194,521提交次数7,931,754

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/two-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

第一遍,暴力计算,复杂度 O(n^2)

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        n = len(nums)
        for i in range(n-1):
            for j in range(i+1,n):
                if nums[i] + nums[j] == target:
                    return [i,j]

在这里插入图片描述
竟然还能击败这么多人吗?难道这不是最土的办法吗?
然后想办法优化下,利用一下 python 本身的方法

第二遍,排序后计算,嗯,其实我也不知道复杂度是多少,但他就是运行时间减少了那么多

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        arr = [_ for _ in nums]
        arr.sort(reverse=True)
        n = len(arr)
        for i in range(n-1):
            for j in range(1,n):
                if arr[i] + arr[j] == target:
                    pos = nums.index(arr[i])
                    if arr[i] != arr[j]:
                        return [pos,nums.index(arr[j])]
                    else:
                        return [pos,nums[pos+1:].index(arr[j])+pos+1]

在这里插入图片描述
在这里插入图片描述
第三遍,利用集合set来看看

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        n = {}
        for i in range(len(nums)):
            if nums[i] in n.keys():
                n[nums[i]] = (n[nums[i]] + [i])[:2]
            else:
                n[nums[i]] = [i]
        for i in n.keys():
            if target == i * 2:
                if len(n[i])>1:
                    return n[i]
                continue
            
            if target - i in n.keys():
                return [n[i][0],n[target - i][0]]

https://leetcode.cn/submissions/detail/403539238/
在这里插入图片描述
内存消耗越来越大了。。。到底怎么能把内存消耗也减掉一些呢
第四遍,实在搞不懂,抄一下官方题解吧

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        hashtable = dict()
        for i, num in enumerate(nums):
            if target - num in hashtable:
                return [hashtable[target - num], i]
            hashtable[nums[i]] = i
        return []

在这里插入图片描述
在这里插入图片描述
????诧异了,执行时间居然比我第三遍的还多一点。。。吓得我多执行了几次第三遍代码,哦,赶巧了啊,平均用时还是40多一点,嗯这个题目就确定了,用hashtable、dict之类的方法就是最好的办法了

2. 两数相加

给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。

在这里插入图片描述

示例 1:
输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[7,0,8]
解释:342 + 465 = 807.
示例 2:
输入:l1 = [0], l2 = [0]
输出:[0]
示例 3:
输入:l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
输出:[8,9,9,9,0,0,0,1]

提示:
每个链表中的节点数在范围 [1, 100] 内
0 <= Node.val <= 9
题目数据保证列表表示的数字不含前导零
通过次数1,641,150提交次数3,875,235

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/add-two-numbers
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

老顾是个野路子,链表是个啥东西也都是最近才开始接触,平时工作里真就没用上过这东西。。。
还好题目中代码给了个 ListNode 的构造,不用一头雾水的琢磨了,然后大概也明白 Node 是个什么东西了,就琢磨了第一个版本的代码

class Solution:
    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:
        u = l1
        d = l2
        r = ListNode()
        z = r
        f = 0
        n = 0
        while u or d or n>0:
            if f:
                r.next = ListNode()
                r = r.next
            s = (u.val if u else 0) + (d.val if d else 0) + n
            r.val = s % 10
            n = s // 10
            u = u.next if u else None
            d = d.next if d else None
            f = 1
        return z

在这里插入图片描述

其实这个题,就是逆序的10进制加法,不过所有数都是倒着的,第一个是各位数,第二位是十位数,第三位是千位数这样的。。。最后返回的链表要求也是逆序的,这就ok

嗯。。。。用了很多没啥意义的变量,纯粹是懒得改了,提交的时候就是这样,算法好像也没啥算法,老顾对链表真的不懂,不知道这种单向链表(也不知道对不对)怎么就能方便的返回每个节点的值,就这么用本办法弄出来了,然后开始学习,去看官方题解。。。好吧,竟然没有 python 版本的题解,而 java 的和 c# 的,居然方法内的内容一毛一样。。。除了变量更容易让人读懂,和老顾的写法也没啥本质区别了。。。瞎猫碰到死耗子了

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

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

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

提示:
0 <= s.length <= 5 * 104
s 由英文字母、数字、符号和空格组成
通过次数2,182,219提交次数5,580,531

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/longest-substring-without-repeating-characters
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

还好,这个题目看着就很简单,嗯,从第一个字符遍历,然后记录遍历的起始位置,碰到重复的字符,记录长度,并和最大长度比较,然后遍历的起始位置从重复的字符后一个开始。。。嗯,思路很清晰,来,写代码了

class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        n = len(s)
        if n<2:
            return n
        
        mx = 1
        # 576ms,15.1mb
        pos = 0

        while pos < n:
            nxt = 1
            if pos + nxt == n:
                break
            final = 0
            while s[pos + nxt] not in s[pos:pos + nxt]:
                if mx < nxt + 1:
                    mx = nxt + 1
                nxt += 1
                if pos + nxt == n:
                    final = 1
                    break
            if final == 1:
                break
            pos += s[pos:pos + nxt].index(s[pos + nxt]) + 1
        

        return mx

在这里插入图片描述
额。。。。这个成绩有点惨不忍睹啊。。。。倒数的前8%。。。。。琢磨琢磨怎么给优化一下,思路应该没什么大问题吧?
嗯,pos 和 nxt 意义不大,不如取消这两个变量,直接用字符串代替,也不再用 s[pos:pos+nxt] 方式计算,直接用一个字符串代替这一堆

class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        n = len(s)
        if n<2:
            return n
        mx = 1
        # 100ms,15.1mb
        l = ''
        for i in range(n):
            while s[i] in l:
                l = l[1:]
            l += s[i]
            mx = max(mx,len(l))
 
        return mx

嗯。。。。看着舒服很多,这次不至于那么惨的成绩了吧,看看先
https://leetcode.cn/submissions/detail/403660974/
在这里插入图片描述
嗯,碰到一次赶巧的成绩,那估计我的这个代码也没啥问题了,翻了翻官方题解。。。。好吧,不能说没啥区别,只能说完全一个路子

4. 寻找两个正序数组的中位数

给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。
算法的时间复杂度应该为 O(log (m+n)) 。

示例 1:
输入:nums1 = [1,3], nums2 = [2]
输出:2.00000
解释:合并数组 = [1,2,3] ,中位数 2
示例 2:
输入:nums1 = [1,2], nums2 = [3,4]
输出:2.50000
解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5

提示:
nums1.length == m
nums2.length == n
0 <= m <= 1000
0 <= n <= 1000
1 <= m + n <= 2000
-106 <= nums1[i], nums2[i] <= 106
通过次数889,905提交次数2,135,574

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/median-of-two-sorted-arrays
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

其实,题目到是真不难,问题在于要理解题意。。。开始没弄明白,什么叫中位数,看了看两个示例,还以为是平均数,一提交,人家不认。。。
在这里插入图片描述
额。。。。那中位数是啥?难道是两个数组中合并后,最中间的那一个或两个数的平均数?那就再试试吧

一通操作猛如虎,还好成绩不是250

class Solution:
    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
        arr = nums1 + nums2
        arr.sort()
        n = (len(arr) + 1) // 2 - 1
        if len(arr) % 2 == 1:
            return arr[n]
        else:
            return (arr[n] + arr[n+1]) / 2

在这里插入图片描述
当然,这里的运算取巧了,毕竟不管 js 也好,python 也好,排序已经不是主要目标了,通常都会直接用系统提供的办法完成,这次只是确定了中位数的概念。。。。嗯,试着不用自身的 sort ,自己来按顺序插入数字。。。反而慢了一半,算了,不折腾了。。。估计这个题考的目的就是排序插入新数组,70ms完成应该也可以了,就当我过了,嘿嘿
说句题外话,这个题目的评价难度居然是困难,没看出困难在哪里。。。。

5. 最长回文子串

给你一个字符串 s,找到 s 中最长的回文子串。
如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。

示例 1:
输入:s = “babad”
输出:“bab”
解释:“aba” 同样是符合题意的答案。
示例 2:
输入:s = “cbbd”
输出:“bb”

提示:
1 <= s.length <= 1000
s 仅由数字和英文字母组成
通过次数1,322,154提交次数3,534,763

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/longest-palindromic-substring
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

第一遍,还是暴力思路,这人呐,脑子闲置的久了,就用不上了。。。

class Solution:
    def longestPalindrome(self, s: str) -> str:
        
        n = len(s)
        if n < 2:
            return s

        r = s[0]

        for i in range(n):
            for j in range(i+1,n+1):
                if s[i:j] == s[i:j][::-1]:
                    if j-i>len(r):
                        r = s[i:j]

        return r

然后,不出所料的没有能通过
在这里插入图片描述
这个是真没想法啊。。。。只好去看题解,嗯嗯嗯嗯,学了很多写法,印象最深刻的,并且自己能理解透的,也就是那个Manacher算法。。。设计真精巧啊

class Solution:
    def longestPalindrome(self, s: str) -> str:
        r = ''
        t = '^#' + '#'.join(s) + '#$'
        n = len(t)
        p = [0 for _ in range(n)]
        for i in range(1,n-1):
            while t[i - p[i] - 1] == t[i + p[i] + 1]:
                p[i] += 1
        mx = max(p)
        idx = p.index(mx)
        b = (idx - mx) // 2
        r = s[b:b+mx]
        return r

在这里插入图片描述

这。。。。跑了好几遍,基本都在1000ms左右?点开提交结果一看。。。排不上号啊。。。

在这里插入图片描述
看来,还得继续学习,而且看官方题解已经不够了,得学别人的写法了,好在,可以点执行用时分布里的时间点看别人的代码,真棒

先找了个900ms左右的答案。。。嗯中心扩散法,学习学习

# 以下内容抄自leetcode第5题908ms答案,实际运行能达到600ms左右
class Solution:
    def longestPalindrome(self, s: str) -> str:
        #暴力解法
        # cur_str = max_str = ''
        # for i in range(len(s)):
        #     for j in s[i:]:
        #         cur_str += j
        #         if cur_str == cur_str[::-1] and len(cur_str) > len(max_str):
        #             max_str = cur_str
        #     cur_str = ''
        # return max_str

        #中心扩散法
        left = right = start = 0
        cur_len = max_len = 1 
        for i in range(len(s)):
            left = i - 1
            right = i +1
            while left >= 0 and s[i] == s[left]:
                left -= 1
                cur_len += 1
            while right < len(s) and s[i] == s[right]:
                right += 1
                cur_len += 1
            while left >= 0 and right < len(s) and s[left] == s[right]:
                left -= 1
                right += 1
                cur_len += 2
                print(s[left], cur_len,end ='QWQ ')
            while cur_len > max_len:
                max_len = cur_len
                start = left + 1
            cur_len = 1                                   #少了这句找了一小时bug
            print(start, end='')
            print(max_len)
        return s[start: start + max_len]


# 以下内容抄自leetcode第5题800ms答案,实际运行能达到600ms左右
class Solution:
    def longestPalindrome(self, s: str) -> str:
        palindrome = ''
        for i in range(len(s)):
            len1 = len(self.getLongestPalindrome(s,i,i))
            if len1> len(palindrome):
                palindrome = self.getLongestPalindrome(s,i,i)
            len2 = len(self.getLongestPalindrome(s,i,i+1))
            if len2> len(palindrome):
                palindrome = self.getLongestPalindrome(s,i,i+1)
        return palindrome
        
    
 
    def getLongestPalindrome(self,s,l,r):
        while l>=0 and r<len(s) and s[l]==s[r]:
            l-=1
            r+=1
        return s[l+1:r]

可惜只能看到答案,不知道是哪位同学提交的,嗯,都是提交的源代码,我一个字符都没改动过的。
这两个答案都是中心扩散法,老顾就不说题解了,自己写一遍试试看,其他同学关于中心扩散法的说明很多,官方题解里也有

# 老顾自己搞一版
class Solution:
    def longestPalindrome(self, s: str) -> str:
        n = len(s)
        if n < 2 or s == s[::-1]:
            return s
        t = s[0]
        for i in range(n):
            mx = 1
            while i - mx >= 0 and i + mx < n and s[i - mx] == s[i + mx]:
                r = s[i - mx:i + mx + 1]
                mx += 1
                if len(r) > len(t):
                    t = r
            mx = 1
            while i - mx + 1 >= 0 and i + mx < n and s[i - mx + 1] == s[i + mx]:
                r = s[i - mx + 1:i + mx + 1]
                mx += 1
                if len(r) > len(t):
                    t = r
        return t

在这里插入图片描述
额。。。。。。这执行用时超出我的预料啊,我还以为也就600ms左右呢。。。。

然后,我们来抄个最厉害的答案吧,40ms执行时间的。。。

# 以下内容抄自leetcode第5题40ms答案
class Solution:
    def longestPalindrome(self, s: str) -> str:        
        if len(s) < 2 or s == s[::-1]:            
            return s        
        res = s[0]        
        maxlen = 1        
        for i in range(1, len(s)):            
            odd = s[i - maxlen - 1: i + 1]
            even = s[i - maxlen: i + 1]
            if even == even[::-1] and i - maxlen >= 0:
                res = even
                maxlen += 1
                continue
            if odd == odd[::-1] and i - maxlen - 1 >= 0:
                res = odd
                maxlen += 2
                continue
        return res

https://leetcode.cn/submissions/detail/403938742/
在这里插入图片描述
肯定是我的电脑和网络问题,竟然跑了几次都没挨到40,人家的最高成绩是36ms。。。。
这位的办法更直接,直接判断当前位置按最大长度中心扩散,得到单双两个字符串,如果其中一个是回文。。。省略了前边的判定,估计在python中好用,其他语言环境就难言了

另一个更暴力的

# 以下内容抄自leetcode第5题56ms答案
class Solution:
    def longestPalindrome(self, s: str) -> str:#
        res=''
        for i in range(len(s)):
            start=max(0,i-len(res)-1)
            temp=s[start:i+1]
            if temp==temp[::-1]:
                res=temp
            else:
                temp=temp[1:]
                if temp==temp[::-1]:
                    res=temp
        return res

在这里插入图片描述
效率虽然略有不如前边的,但他的思路更简洁,实现起来更简单啊。。。。

抄个java的40ms看看。。。其实也差不多。。。

// 以下内容抄自leetcode第5题40ms答案
class Solution {
    public String longestPalindrome(String s) {
        if(s.length()==0){
            return s;
        }
        if(s.length()==1){
            return s;
        }
        if(s.length()==2){
            if(s.charAt(0)==s.charAt(1)){
                return s;
            }else{
                return s.substring(0,1);
            }
        }
        String result="";
        for(int i =1;i<s.length();i++){
            char a = s.charAt(i);
            int start = i-1;
            int end = i+1;
            while (start>=0&&end<=s.length()-1){
                if(end-i==1){
                    while (s.charAt(start)==a){
                        start -= 1;
                        if(start<0){
                            break;
                        }
                    }
                    while (s.charAt(end)==a){
                        end +=1;
                        if(end>s.length()-1){
                            break;
                        }
                    }
                    String temp = s.substring(start+1,end);
                    if(temp.length()>result.length()){
                        result=temp;
                    }
                }
                if(start<0||end>s.length()-1){
                    break;
                }
                if(s.charAt(start)==s.charAt(end)){
                    String temp = s.substring(start,end+1);
                    if(temp.length()>result.length()){
                        result=temp;
                    }
                    start--;
                    end++;
                    continue;
                }else{
                    break;
                }
            }
        }
        return result;
    }
}

也是中心扩散法,嗯确定了,manacher方法很精巧,很容易记,但效率真不如中心扩散

6. 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:
输入:s = “PAYPALISHIRING”, numRows = 3
输出:“PAHNAPLSIIGYIR”
示例 2:
输入:s = “PAYPALISHIRING”, numRows = 4
输出:“PINALSIGYAHRPI”
解释:
P I N
A L S I G
Y A H R
P I
示例 3:
输入:s = “A”, numRows = 1
输出:“A”

提示:
1 <= s.length <= 1000
s 由英文字母(小写和大写)、‘,’ 和 ‘.’ 组成
1 <= numRows <= 1000
通过次数531,132提交次数1,019,546

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/zigzag-conversion
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

呦,这个应该不难吧?结果老顾自己琢磨了半天,才弄出第一个版本

class Solution:
    def convert(self, s: str, numRows: int) -> str:
        n = len(s)
        if n <= numRows:
            return s
        if numRows==1:
            return s
        r = ['' for _ in range(numRows)]
        x = numRows*2-2
        for i in range(numRows):
            r[i] = [s[_] if _%x==i or (_%x>=numRows and numRows-(_%x-numRows+1)-1==i) else '' for _ in range(n)]
        #for i in r:
        #    print(''.join(i))

        return ''.join([''.join(i) for i in r])

其实就是一个折叠位置的取余与原有高度的差问题。。。嗯,这个效率太感人了
在这里插入图片描述
惨不忍睹啊。。赶紧简化 代码

class Solution:
    def convert(self, s: str, numRows: int) -> str:
        n = len(s)
        if n <= numRows:
            return s
        if numRows==1:
            return s
        x = numRows*2-2
        r = ['' for _ in range(numRows)]
        for i in range(n):
            r[min(i % x,x-i%x)] += s[i]
        return ''.join(r)

好像也诶怎么动,就是把按行循环改成按字符循环。。。第一版是按行从字符串里提取应该在该行的字符,第二版是按字符分配到应该去的行。。。。结果效率。。。
在这里插入图片描述
效率还是不错的。。。问题是才53%??
在这里插入图片描述
这得抄作业?来个36ms的答案看看!

# 以下内容抄自leetcode第6题36ms答案
class Solution:
    def convert(self, s: str, numRows: int) -> str:
        ans = ['']*numRows
        flag = -1
        cnt = 0
        if numRows<2:
            return s 
        for ch in s:
            ans[cnt] +=ch 
            if cnt ==0 or cnt ==numRows-1:
                flag = flag * -1 
            cnt += flag
        
        return ''.join(ans)

额。。。。感觉差不多啊,为什么比不过呢?算了,这个答案分布,基本就差那么几ms,老顾是不懂的了,不跟你们这帮牲口拼了,继续做下一题去了

7. 整数反转

给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。
如果反转后整数超过 32 位的有符号整数的范围 [−2^31, 2^31 − 1] ,就返回 0。
假设环境不允许存储 64 位整数(有符号或无符号)。

示例 1:
输入:x = 123
输出:321
示例 2:
输入:x = -123
输出:-321
示例 3:
输入:x = 120
输出:21
示例 4:
输入:x = 0
输出:0

提示:
-231 <= x <= 231 - 1
通过次数1,150,381提交次数3,247,643

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/reverse-integer
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

Hmmmmmmm,我的电脑难道是32位的?

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

在这里插入图片描述
额。。。。。。我都作弊了,居然还不是头部10%?
算了,这个题还是按照不作弊的方式自己尝试下吧。

class Solution:
    def reverse(self, x: int) -> int:
        y = 0
        z = 1 
        if x < 0:
            z = -1
            x *= z
        while x > 0:
            y = y * 10 + x % 10
            x //= 10
        y *= z
        if y > (2**31 - 1) or y < (2**31 * -1):
            return 0
        return y        

https://leetcode.cn/submissions/detail/403955924/在这里插入图片描述
嗯。。。。老顾真的不知道怎么装作不支持64位。。。所以最后的那个比大小估计是有问题的,然后答案估计也很集中在几个时间点上,就不抄答案了这次

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

请你来实现一个 myAtoi(string s) 函数,使其能将字符串转换成一个 32 位有符号整数(类似 C/C++ 中的 atoi 函数)。
函数 myAtoi(string s) 的算法如下:
读入字符串并丢弃无用的前导空格
检查下一个字符(假设还未到字符末尾)为正还是负号,读取该字符(如果有)。 确定最终结果是负数还是正数。 如果两者都不存在,则假定结果为正。
读入下一个字符,直到到达下一个非数字字符或到达输入的结尾。字符串的其余部分将被忽略。
将前面步骤读入的这些数字转换为整数(即,“123” -> 123, “0032” -> 32)。如果没有读入数字,则整数为 0 。必要时更改符号(从步骤 2 开始)。
如果整数数超过 32 位有符号整数范围 [−2^31, 2^31 − 1] ,需要截断这个整数,使其保持在这个范围内。具体来说,小于 −231 的整数应该被固定为 −2^31 ,大于 2^31 − 1 的整数应该被固定为 2^31 − 1 。
返回整数作为最终结果。
注意:
本题中的空白字符只包括空格字符 ’ ’ 。
除前导空格或数字后的其余字符串外,请勿忽略 任何其他字符。

示例 1:
输入:s = “42”
输出:42
解释:加粗的字符串为已经读入的字符,插入符号是当前读取的字符。
第 1 步:“42”(当前没有读入字符,因为没有前导空格)
^
第 2 步:“42”(当前没有读入字符,因为这里不存在 ‘-’ 或者 ‘+’)
^
第 3 步:“42”(读入 “42”)
^
解析得到整数 42 。
由于 “42” 在范围 [-2^31, 2^31 - 1] 内,最终结果为 42 。
示例 2:
输入:s = " -42"
输出:-42
解释:
第 1 步:" -42"(读入前导空格,但忽视掉)
^
第 2 步:" -42"(读入 ‘-’ 字符,所以结果应该是负数)
^
第 3 步:" -42"(读入 “42”)
^
解析得到整数 -42 。
由于 “-42” 在范围 [-2^31, 2^31 - 1] 内,最终结果为 -42 。
示例 3:
输入:s = “4193 with words”
输出:4193
解释:
第 1 步:“4193 with words”(当前没有读入字符,因为没有前导空格)
^
第 2 步:“4193 with words”(当前没有读入字符,因为这里不存在 ‘-’ 或者 ‘+’)
^
第 3 步:“4193 with words”(读入 “4193”;由于下一个字符不是一个数字,所以读入停止)
^
解析得到整数 4193 。
由于 “4193” 在范围 [-2^31, 2^31 - 1] 内,最终结果为 4193 。

提示:
0 <= s.length <= 200
s 由英文字母(大写和小写)、数字(0-9)、’ ‘、’+‘、’-’ 和 ‘.’ 组成
通过次数544,287提交次数2,544,799

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/string-to-integer-atoi
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

嗯,这个题其实非常简单,主要就是,从读入符号看是,后边必须是数字这么一个隐藏条件

class Solution:
    def myAtoi(self, s: str) -> int:
        s = s.strip()
        x = ''
        f = 1
        if len(s)==0:
            return 0
        if s[0] in '+-':
            if s[0] == '-':
                f *= -1
            s = s[1:]
        while len(s)>0 and s[0].isnumeric():
            x += s[0]
            s = s[1:]
        e = int(x) if len(x)>0 and x != '-' else 0
        e *= f
        if e < 2**31 * -1:
            e = 2**31 * -1
        if e >= 2**31:
            e = 2**31 - 1
        return e

在这里插入图片描述
牲口太多了。。。才30%不到的名次
在这里插入图片描述

竟然还有20ms的答案。。。比不了比不了

9. 回文数

给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。
回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
例如,121 是回文,而 123 不是。

示例 1:
输入:x = 121
输出:true
示例 2:
输入:x = -121
输出:false
解释:从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。
示例 3:
输入:x = 10
输出:false
解释:从右向左读, 为 01 。因此它不是一个回文数。

提示:
-2^31 <= x <= 2^31 - 1

进阶:你能不将整数转为字符串来解决这个问题吗?
通过次数1,279,736提交次数2,268,913

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/palindrome-number
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

class Solution:
    def isPalindrome(self, x: int) -> bool:
        return str(x) == str(x)[::-1]

在这里插入图片描述
你说不转字符串我就不转?

嗯,那就不转吧

class Solution:
    def isPalindrome(self, x: int) -> bool:
        if x == 0:
            return True
        if x < 0 or x % 10 == 0:
            return False
        y = x
        z = 0
        while y > 0:
            z = z * 10 + y % 10
            y //= 10
            if y == z:
                return True
        return x == z

在这里插入图片描述
在这里插入图片描述
最好成绩52ms,题目评价简单,也就这样了

10. 正则表达式匹配

给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 ‘.’ 和 ‘’ 的正则表达式匹配。
‘.’ 匹配任意单个字符
'
’ 匹配零个或多个前面的那一个元素
所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。

示例 1:
输入:s = “aa”, p = “a”
输出:false
解释:“a” 无法匹配 “aa” 整个字符串。
示例 2:
输入:s = “aa”, p = “a*”
输出:true
解释:因为 ‘’ 代表可以匹配零个或多个前面的那一个元素, 在这里前面的元素就是 ‘a’。因此,字符串 “aa” 可被视为 ‘a’ 重复了一次。
示例 3:
输入:s = “ab”, p = ".
"
输出:true
解释:"." 表示可匹配零个或多个('’)任意字符(‘.’)。

提示:
1 <= s.length <= 20
1 <= p.length <= 30
s 只包含从 a-z 的小写字母。
p 只包含从 a-z 的小写字母,以及字符 . 和 *。
保证每次出现字符 * 时,前面都匹配到有效的字符
通过次数345,735提交次数1,118,182

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/regular-expression-matching
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

老顾自认自己的正则还不错,这个题目就是根据正则来的,不过只要求实现长度*和字符集.
先用正则包来完成下看看情况

import re
class Solution:
    def isMatch(self, s: str, p: str) -> bool:
        return True if re.match(p+'$',s) else False

在这里插入图片描述
我去。。。。这成绩倒数了啊,大佬这么多,都自己实现的正则算法?

嗯,自己写个尝试看看,第一步,整理正则,为什么要整理正则呢?因为很多时候,新手的正则写得很冗余,有效部分其实并不多

# 两个正则片段,完全等价的哦
a*b*.*c* === .*
a*aaa === a{3,}
a*a*a*a*a*a* === a*
a*.*b*.*a*aa*a* === .*a{1,}

这么一整理,需要处理的片段就会少很多了

    def formatRegexPattern(self,p):
        pattern = []
        for i in p:
            if len(pattern) == 0:
                pattern.append({'c':i,'l':1,'r':1})
                continue
            if i == '*':
                pattern[-1]['r'] = -1
                pattern[-1]['l'] -= 1
                while len(pattern) > 1 and pattern[-1]['c'] == '.':
                    isPop = False
                    if pattern[-2]['r'] == -1 and pattern[-2]['l'] == 0:
                        pattern.pop(-2)
                        isPop = True
                    if not isPop:
                        break
                while len(pattern) > 1 and pattern[-2]['c'] == '.' and pattern[-2]['r'] == -1:
                    isPop = False
                    if pattern[-1]['l'] == 0:# and pattern[-2]['l'] == 0:
                        pattern.pop(-1)
                        isPop = True
                    if not isPop:
                        break
                while len(pattern) > 1 and pattern[-1]['c'] == '.' and pattern[-2]['c'] == '.':
                    pattern[-2]['l'] += pattern[-1]['l']
                    if pattern[-2]['r'] == -1 or pattern[-1]['r'] == -1:
                        pattern[-2]['r'] = -1
                    pattern.pop(-1)
                continue
            if i == pattern[-1]['c']:
                pattern[-1]['l'] += 1
                pattern[-1]['r'] += 1 if pattern[-1]['r'] > 0 else 0
                continue
            pattern.append({'c':i,'l':1,'r':1})
        return pattern

嗯,弄好了正则合并后,老顾开始琢磨怎么实现正则了,开始写了一大片代码。。。问题是没递归,没调用,纯用循环判断各种情况,最后写不下去了。。。。自己把自己恶心到了

换个思路,正则匹配是按片段进行的,当上一个片段符合,就匹配下一个片段

那么,用递归去匹配当前片段,当前字符串,然后将剩余的片段递归到下一次匹配,传递剩余字符串就好了

再然后,唯一需要注意的就是长度问题了,最后好歹实现出来了,帖个代码先

class Solution:
    def formatRegexPattern(self,p):
        pattern = []
        for i in p:
            if len(pattern) == 0:
                pattern.append({'c':i,'l':1,'r':1})
                continue
            if i == '*':
                pattern[-1]['r'] = -1
                pattern[-1]['l'] -= 1
                while len(pattern) > 1 and pattern[-1]['c'] == '.':
                    isPop = False
                    if pattern[-2]['r'] == -1 and pattern[-2]['l'] == 0:
                        pattern.pop(-2)
                        isPop = True
                    if not isPop:
                        break
                while len(pattern) > 1 and pattern[-2]['c'] == '.' and pattern[-2]['r'] == -1:
                    isPop = False
                    if pattern[-1]['l'] == 0:# and pattern[-2]['l'] == 0:
                        pattern.pop(-1)
                        isPop = True
                    if not isPop:
                        break
                while len(pattern) > 1 and pattern[-1]['c'] == '.' and pattern[-2]['c'] == '.':
                    pattern[-2]['l'] += pattern[-1]['l']
                    if pattern[-2]['r'] == -1 or pattern[-1]['r'] == -1:
                        pattern[-2]['r'] = -1
                    pattern.pop(-1)
                continue
            if i == pattern[-1]['c']:
                pattern[-1]['l'] += 1
                pattern[-1]['r'] += 1 if pattern[-1]['r'] > 0 else 0
                continue
            pattern.append({'c':i,'l':1,'r':1})
        return pattern
    def IsMatch(self,s,p):
        if len(s) == 0 and len(p) == 0:
            return True
        if len(s) == 0 and sum([n['l'] for n in p]) > 0:
            return False
        if len(s) == 0 and sum([n['l'] for n in p]) == 0:
            return True
        if len(s) > 0 and len(p) == 0:
            return False
        r = False
        f = p[0]
        c = f['c']
        l = f['l']
        m = f['r']
        if l > 0:
            if l > len(s):
                return False
            v = s[:l]
            if c != '.' and c * l != v:
                return False
            s = s[l:]
        if m > l:
            for i in range(m - l + 1):
                if c * i == s[:i] or c == '.':
                    r = r or self.IsMatch(s[i:],p[1:])
                    if r:
                        break
        elif m == -1:
            for i in range(len(s) + 1):
                if c * i == s[:i] or c == '.':
                    r = r or self.IsMatch(s[i:],p[1:])
                    if r:
                        break
        else:
            r = r or self.IsMatch(s,p[1:])
        return r

    def isMatch(self, s: str, p: str) -> bool:
        pattern = self.formatRegexPattern(p)
        return self.IsMatch(s,pattern)

https://leetcode.cn/submissions/detail/404116311/
在这里插入图片描述
在这里插入图片描述
呦呵,成绩还不错,差一点就到头部了,一个正则实现琢磨了两天,终于搞定,学习告一段落,下次继续学习

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/358061.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

大数据处理学习笔记1.5 掌握Scala内建控制结构

文章目录零、本讲学习目标一、条件表达式&#xff08;一&#xff09;语法格式&#xff08;二&#xff09;执行情况&#xff08;三&#xff09;案例演示任务1、根据输入值的不同进行判断任务2、编写Scala程序&#xff0c;判断奇偶性二、块表达式&#xff08;一&#xff09;语法格…

科学推理~

科学推理 【物理】 1、力学 重力 重力并不是指向地心的&#xff0c;只有赤道可以 弹力 【重点】判断弹力方向 相互作用力 摩擦力 静摩擦力 滑动摩擦力 注意&#xff1a;最大静摩擦力默认等于滑动摩擦力 压强 固体压强 液体压强 连通器 气体压强 气体对外做功&#xff0c;T 下…

1 月份 NFT 行业报告

Jan.2023&#xff0c; DanielData Source: NFT Monthly Report1 月是近一年来代币价格最好的一个月&#xff0c;ETH、BTC 和 altcoins 的涨幅是 7 月以来最猛的。自然&#xff0c;这导致了 NFT 行业的交易量和市值增加。一些指标是可以预测的&#xff0c;比如已完成的投资轮数继…

BI知识全解,值得收藏

2021年度&#xff0c;中国商业软件市场的增长趋势是快速增长的&#xff0c;达到7.8亿美元&#xff0c;同比增长34.9%。商业智能BI在企业应用中具有巨大的价值&#xff0c;并逐渐成为现代企业信息化和数字化转型的基础。所以&#xff0c;全面了解BI&#xff0c;对于企业管理是非…

100天精通Python(数据分析篇)——第76天:Pandas数据类型转换函数pd.to_numeric(参数说明+实战案例)

文章目录专栏导读一、to_numeric参数说明0. 介绍1. arg1&#xff09;接收列表2&#xff09;接收一维数组3&#xff09;接收Series对象2. errors1&#xff09;errorscoerce2&#xff09;errors ignore3. downcast1&#xff09;downcastinteger2&#xff09;downcastsigned3&…

Spring中bean的生命周期(通俗易懂)

具体流程 bean的生命周期分4个阶段&#xff1a;   1.实例化   2.属性赋值   3.初始化   4.销毁 实例化就是在内存中new()出一个对象&#xff0c;属性赋值就是给那些被Autowired修饰的属性注入对象&#xff0c;销毁是在Spring容器关闭时触发&#xff0c;初始化的步骤比较…

隐私计算头条周刊(2.13-2.19)

开放隐私计算收录于合集#企业动态44个#周刊合辑44个#政策聚焦37个#隐私计算91个#行业研究36个开放隐私计算开放隐私计算OpenMPC是国内第一个且影响力最大的隐私计算开放社区。社区秉承开放共享的精神&#xff0c;专注于隐私计算行业的研究与布道。社区致力于隐私计算技术的传播…

【JavaEE】Servlet学后大汇总

JavaEE之Servlet一、WEB容器二、Servlet常用API和简单说明三、Servlet生命周期Servlet对象是什么时候被创建的&#xff1f;Servlet被称为假单例一个请求对应一个request和一个response四、Servlet属性设置——三个范围&#xff08;请求、会话、应用&#xff09;五、会话、过滤器…

每日学术速递2.20

CV - 计算机视觉 | ML - 机器学习 | RL - 强化学习 | NLP 自然语言处理 Subjects: cs.CV 1.Boundary Guided Mixing Trajectory for Semantic Control with Diffusion Models 标题&#xff1a;用于扩散模型语义控制的边界引导混合轨迹 作者&#xff1a;Ye Zhu, Yu Wu, Zhi…

Android 开发布局笔记01 控件

Relative Layout 前端界面代码 <?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:app"http://schemas.android.com/apk/res-auto"xmlns:tools&qu…

数据结构与算法(Java版) | 线性结构和非线性结构

之前&#xff0c;我们说过&#xff0c;数据结构是算法的基础&#xff0c;因此接下来在这一讲我就要来给大家重点介绍一下数据结构了。 首先&#xff0c;大家需要知道的是&#xff0c;数据结构包括两部分&#xff0c;即线性结构和非线性结构。知道这点之后&#xff0c;接下来我…

flex一把梭

flex 使用display:flex&#xff0c;可以让一个元素变成弹性容器&#xff08;flex容器&#xff09;&#xff0c;该元素中的直接子元素成为弹性项&#xff08;flex项&#xff09; flex-direction 使用flex-direction可以控制flex容器的主轴的方向&#xff1a;垂直&#xff08;…

躬身入局,干货分享,2023年春招后端技术岗(Python)面试实战教程,Offer今始为君发

早春二月&#xff0c;研发倍忙&#xff0c;杂花生树&#xff0c;群鸥竟飞。为什么&#xff1f;因为春季招聘&#xff0c;无论是应届生&#xff0c;还是职场老鸟&#xff0c;都在摩拳擦掌&#xff0c;秣马厉兵&#xff0c;准备在面试场上一较身手&#xff0c;既分高下&#xff0…

Allegro如何让测量时显示双单位操作指导

Allegro如何让测量时显示双单位操作指导 在用Allegro做PCB设计的时候,时常会需要使用到测量命令,通常显示的一个单位,比如mil,如下图 当希望除了看到mil单位的值,又同时能够看到mm单位的值,省去换算的时间 具体设置如下 点击Setup点击User Preference

Linux服务:Nginx服务部署及基础配置

目录 一、Nginx介绍 1、Nginx简介 2、I/O模型相关概念 3、Nginx事件驱动模型 二、部署Nginx 1、yum部署Nginx 2、编译安装Nginx 三、Nginx使用 1、基础使用 2、nginx信号 四、web服务选择及优化 1、Nginx与Apache对比 2、Nginx服务调优 一、Nginx介绍 1、Nginx简…

SAP ABAP

方法一&#xff1a; REPORT ZDCH_09_TEST2. ************************************************************************ * DATEN DEFINITION * *********************************************************************…

【数据结构】二叉树-堆实现及其堆的应用(堆排序topK问题)

文章目录一、堆的概念及结构二、堆的实现1.结构的定义2.堆的初始化3.堆的插入4.堆的向上调整5.堆的删除6.堆的向下调整7.取出堆顶元素8.返回堆的元素个数9.判断堆是否为空10.打印堆中的数据11.堆的销毁三、完整代码1.Heap.h2.Heap.c3.test.c四、堆排序1.堆排序2.建堆3.选数4.完…

Shopee、ebay、亚马逊等跨境卖家了解测评的一篇干货

随着时代的发展&#xff0c;大家越来越喜欢网购&#xff0c;国外也有亚马逊、沃尔码、阿里国际、速卖通、ebay、shopee、Lazada、ozon、temu等等&#xff0c;而国外这些平台也有很大的市场&#xff0c;跨境电商也随时诞生&#xff0c;而当今社会环境实体生意越来越难做&#xf…

DAMA认证|数据治理产业上规模需要做到“三化”

数据治理是开启数据安全体系化建设的第一步&#xff0c;需要从产业层面做大做强&#xff0c;支撑数据安全整体框架&#xff0c;为数据流通提供安全保障&#xff0c;推动促进数字化产业进一步发展。 规模化发展是数据治理产业的瓶颈&#xff0c;行业数字化业务的复杂性和过多的定…

k8s安装tekton,编写task

文章目录一、官方安装二、国内资源安装安装tekton安装dashboard安装CLI三、demo编写task.yaml编写taskRun.yaml使用tkn命令查看参考文章一、官方安装 地址&#xff1a;https://tekton.dev/docs/installation/pipelines/#installing-tekton-pipelines-on-kubernetes 注意&#…