leetcode 刷题笔记【简单版】

.index : 查找索引

A[::] : 对数组进行切片并从前往后取值

A[::-1] : 对数组进行切片并从后往前取值

递归调用:函数在运行时调用自己,可求解两数之和

set() : 创建集合(集合内不会有重复的元素!!!可用于判断重复字符)但是无序的,无下标!!

可通过原列表和创建set后的长度是否一致来判断有无重复字符。

pairwise() : 从左到右输出步长为2的数组对

enumerate() : 同时获得索引和值

stack : 栈, 先入后出。 stack.pop() 入    stack.append()出

replace :将字符串中的某一元素替换成指定元素,但不会改变原来字符串的内容。                    str.replace('old', 'new', count])

剔除指定元素,并返回与指定元素不同值的数量和数组:

(第一次完完整整自己敲代码没报错并且输出居然是对的!!

class Solution:
    def removeElement(self, nums: List[int], val: int) -> int:
        k = 0
        for i in range(len(nums)):
            if nums[i] != val:
                nums[k] = nums[i]
                k += 1
        return k 

9.27 刷的第二题也是一次通过!!纪念一下:

(虽然不是最优解,看了解答代码还能再简化,继续努力!!

class Solution:
    def strStr(self, haystack: str, needle: str) -> int:
        if len(haystack) < len(needle): return -1
        if haystack == needle : return 0
        for i in range(len(haystack)-len(needle)+1):
            if haystack[i:i+len(needle)] == needle:
                return i
            i += 1
            if i == len(haystack)-len(needle)+1 and haystack[i:] != needle:
                return -1

今天学二分法:

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。

解析:返回nums中的第一个(最左边)大于或等于target的数的下标。如果所有数都小于target,返回nums的长度。

def lower_bound(nums: List[int], target: int) -> int:
    left, right = 0, len(nums) -1
    while left <= right:
        mid = (left + right) // 2
        if nums[mid] < target:
            left = mid + 1   # 范围缩小到 [mid+1, right]
        else:
            right = mid - 1  # 范围缩小到 [left, mid-1]
    return left

## 相当于循环不变量:
## nums[left - 1] < target
## nums[right + 1] >= target

s.rstrip() : 去除最右边的空格字符

s.split("") : 以“”为间隔进行切片, 可用于计算字符串中单词数

用for循环倒序读字符串,可让i=len(s)-1

检查进位问题:

def plusOne(self, digits: List[int]) -> List[int]:
        cur = 1
        for i in range(len(digits) - 1, -1, -1):
            cur += digits[i]
            digits[i] = cur % 10
            cur //= 10
        return digits if not cur else [cur] + digits  
# 如果cur是none就返回digits,否则返回一个新列表,第一个元素是[cur],后面是digits

int(a,b) : a表示传入的字符串,b表示输出的进制数,可用于非十进制的加法计算

二叉树:

# 递归
class Solution:
    def preorderTraversal(self, root: TreeNode) -> List[int]:
        if not root:
            return []
        # 前序递归
        return [root.val] + self.preorderTraversal(root.left) + self.preorderTraversal(root.right)
        # # 中序递归 
        return self.inorderTraversal(root.left) + [root.val] + self.inorderTraversal(root.right)
        # # 后序递归
        return self.postorderTraversal(root.left) + self.postorderTraversal(root.right) + [root.val]

递归法输出二叉树的深度:

class Solution:
    def maxDepth(self, root: Optional[TreeNode]) -> int:
        if root is None: return 0
        return max(self.maxDepth(root.left), self.maxDepth(root.right)) + 1

生成杨辉三角:

class Solution:
    def generate(self, numRows: int) -> List[List[int]]:
        a = [[1] * (i+1) for i in range(numRows)]
        for i in range (2,numRows):
            for j in range(1,i):
                a[i][j] = a[i-1][j-1] + a[i-1][j]
        return a

买股票问题:如果第i天卖出股票,则最大利润为(该天的股价-前面天数中最小的股价),然后与已知的最大利润比较,如果大于则更新当前最大利润的值。

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        minprice = float('inf')
        maxpro = 0
        for price in prices:
            minprice = min(minprice, price)
            maxpro = max(maxpro, price - minprice)
        return maxpro

异或\oplus运算:相同二进制位为0,不同为1:0 ^ x = x; x ^ x = 0.  可用于消除出现了两次的元素

Excel表:要转成26进制, A的ASCII值为65

class Solution:
    def convertToTitle(self, columnNumber: int) -> str:
        res = ""
        while columnNumber:
            columnNumber -= 1
            columnNumber, y = divmod(columnNumber, 26)
            res = chr(y+65) + res
        return res

pandas.merge(left, right, how: str = 'inner', on=None, left_on=None, right_on=None, left_index: bool = False, right_index: bool = False, sort: bool = False, suffixes='_x', '_y', copy: bool = True, indicator: bool = False, validate=None)  用于合并两个DataFrame

DataFrame[' '].value_counts() : 统计DataFrame中某一标签下的数量

DataFrame.loc(x,y): 取DataFrame的x行y列

bin(x): 得到整数x的二进制数

<< , >>: 二进制数的位运算,分别为对二进制数进行左移和右移

& 符号,x & y ,会将两个十进制数在二进制下进行与运算
| 符号,x | y ,会将两个十进制数在二进制下进行或运算
^ 符号,x ^ y ,会将两个十进制数在二进制下进行异或运算
<< 符号,x << y 左移操作,最右边用 0 填充
>> 符号,x >> y 右移操作,最左边用 0 填充
~ 符号,~x ,按位取反操作,将 x 在二进制下的每一位取反

shift(1): 将DataFrame中所有元素下移一行

dummy_head = ListNode(next=head) #添加一个虚拟节点

同构字符串:如果 s 中的字符可以按某种映射关系替换得到 t ,那么这两个字符串是同构的。

解题思路:找到两个子母中不同字符从左到右的的index 列表是否完全一致

class Solution:
    def isIsomorphic(self, s: str, t: str) -> bool:
        return all(s.index(s[i]) == t.index(t[i]) for i in range(len(s)))

递归法反转链表思路: 定义recur(cur,pre)函数,cur记录当前节点,pre指向前节点(所以开始需要用None给一个空节点), 终止条件是cur为空,res来记录反转后的链表。

class Solution:
    def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
        def recur(cur,pre):
            if not cur: return res
            while cur:
                res = recur(cur.next, cur)
                cur.next = pre
            return res
        return recur(head, None)

完满二叉树:如果有孩子,一定是两个

完全二叉树:除最后一层外所有节点都被填充,且所有节点向左对齐

完美二叉树:所有节点都有两个孩子

汇总区间:返回恰好覆盖数组中所有数字的最小有序区间范围列表。利用双指针求解,指针移动策略是相邻元素之间差1。

2的次幂在二进制下只有首位是1其余位都是0

判断字母异位:字符串不能用set!!可以用哈希表,统计a字符串中每个字母出现的次数(操作为+1),再统计b字符串中每个字母出现的次数(操作为-1),最后若为0则输出True。

class Solution:
    def isAnagram(self, s: str, t: str) -> bool:
    from collections import defaultdict
    if len(s) != len(t):
        return False 
    dic = defacultdict(int)
    for x in s:
        dic[x] += 1 
    for x in t:
        dic[x] -= 1
    for val in dic.values():
        if val != 0:
            return False
    return True

各位相加:给定一个非负整数 num,反复将各个位上的数字相加,直到结果为一位数。返回这个结果。列举0-30的情况可以发现,0特例,1-9输出为数本身,10-18输出与1-9相同,19-27输出也与1-9相同,可见9个数一循环。

class Solution:
    def addDigits(self, num: int) -> int:
        return 9 if (num % 9 == 0 ) and (num != 0) else num % 9

对于二进制数,可以直接用.count("1")来统计位为1的个数。

反转字符串中的元音字母:也用双指针法,注意while和if的条件。

class Solution:
    def reverseVowels(self, s: str) -> str:
        a = set('aeiouAEIOU')
        l, r = 0, len(s) - 1
        s = list(s)
        while l < r:
            if s[l] in a and s[r] in a:
                s[l], s[r] = s[r], s[l]
                l += 1
                r -= 1
            if s[l] not in a:
                l += 1
            if s[r] not in a:
                r -= 1
        return ''.join(s)

.sort():对列表进行排序,默认是升序,用reverse=True可改为降序。

判断有效的完全平方数:二分查找法

class Solution:
    def isPerfectSquare(self, num: int) -> bool:
        l, r = 1, num
        while l < r:
            mid = (l + r) // 2
            if mid * mid < num:
                l = mid + 1
            else:
                r = mid
        return l * l == num

Counter():跟踪值出现的次数,以字典的键值对形式存储,元素作为key,其计数作为value。

Counter类的创建 
>>> c = Counter()  # 创建一个空的Counter类
>>> c = Counter('gallahad')  # 从一个可iterable对象(list、tuple、dict、字符串等)创建
>>> c = Counter({'a': 4, 'b': 2})  # 从一个字典对象创建
>>> c = Counter(a=4, b=2)  # 从一组键值对创建

Counter("aabcdd")
Counter("a") --> 2

重复的子字符串:如果一个字符串s可以通过他的一个子串重复得到,说明将这个字符串重复一遍(s+s),去掉头尾后依然可以找到s自己;如果不能通过子串重复的到,那么s+s中找不到自己。

class Solution:
    def repeatedSubstringPattern(self, s: str) -> bool:
        return s in (s + s)[1:-1]

二进制手表:(这题也泰难了,居然属于简单题吗。。。)

为了方便计算,分别设置了小时数组和分钟数组
递归的四个参数分别代表:剩余需要点亮的灯数量,从索引index开始往后点亮灯,当前小时数,当前分钟数每次进入递归后,先判断当前小时数和分钟数是否符合要求,不符合直接return
for循环枚举点亮灯的情况,从index枚举到10,每次枚举,减少一个需要点亮的灯数量num - 1
从当前已点亮的灯后面选取下一个要点亮的灯 i + 1在hour中增加当前点亮灯的小时数,如果i大于3,当前灯是分钟灯而不是小时灯,则加上0个小时在minute中增加当前点亮灯的分钟数,如果i没有大于3,当前灯是小时灯而不是分钟灯,则加上0分钟当剩余需要点亮的灯数量为0的时候,已枚举完一种情况,根据题目要求的格式加到res列表中返回res

class Solution:
    def readBinaryWatch(self, turnedOn: int) -> List[str]:
        hours = [1, 2, 4, 8, 0, 0, 0, 0, 0, 0]
        minutes = [0, 0, 0, 0, 1, 2, 4, 8, 16, 32]
        res = []
        def backtrack(num, index, hour, minute):
            if hour > 11 or minute >59:
                return
            if num == 0:
                res.append('%d:%02d'%(hour,minute))
                return
            for i in range(index, 10):
                backtrack(num - 1, i + 1, hour + hours[i], minute + minutes[i])
        
        backtrack(turnedOn, 0, 0, 0)
        return res

数字转化为十六进制数:

CONV = "0123456789abcdef"
class Solution:
    def toHex(self, num: int) -> str:
        ans = []
        for _ in range(8):
            ans.append(num%16)
            num //= 16
            if not num:
                break
        return "".join(CONV[n] for n in ans[::-1])

构建回文串:如果回文串长度为偶数,则每个字符都应该出现偶数次;如果长度为奇数,那么只有中间字符出现奇数次,其他字符出现偶数次。

class Solution:
    def longestPalindrome(self, s: str) -> int:
        counter = collections.defaultdict(int)
        res, odd = 0,0 
        for x in s:
            counter[x] += 1
        for count in counter.values():
            amp = count % 2
            res += count - amp
            if amp == 1 : odd = 1
        return res + odd

s.lstrip(' ')  s.rstrip(' ')  s.strip(' '):分别为去除字符串左边、右边、全部的‘ ’ 字符

构造符合要求的矩形:长度 L 和宽度 W 之间的差距应当尽可能小, L>=W,L*W=area

翻译一下,其实就是求area最接近开根的值L。

class Solution:
    def constructRectangle(self, area: int) -> List[int]:
        for i in range(int(sqrt(area)),0,-1):
            if not area % i :  ## 也可以写成 if area % i == 0
                return [area // i, i]

通常一维数组,要寻找任一元素右边(左边)第一个比自己大(小)的元素,且要求 O(n) 的时间复杂度,用单调栈。以下为寻找右边第一个比自己大的元素,并返回该元素,若不存在返回-1。

class Solution:
    def nextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]:
        idx = {x: i for i, x in enumerate(nums1)}
        ans = [-1] * len(nums1)
        st = []
        for x in reversed(nums2):
            while st and x >= st[-1]:
                st.pop()
            if st and x in idx:
                ans[idx[x]] = st[-1]
            st.append(x)
        return ans

二叉搜索树中的众数:中序遍历!!常用

Class Solution:
    # 中序遍历
    def inOrder(self, root:TreeNode, lst):
        if root is None:
            return None
        self.inOrder(root.left, lst)
        lst.append(root.val)
        self.inOrder(root.right, lst)
    def findMode(self, root:Optional[TreeNode]) -> List[int]:
        lst = []  # 根列表
        self.inOrder(root, lst)
        cnt = 1   # 记录当前次数
        maxcnt = 1   # 记录最大次数
        pre = lst[0]  # 记录前一个元素
        res = [lst[0]]   # 保存结果
        for i in range(1, len(lst)):
            if pre == lst[i]:   # 如果前一个元素和当前元素相同,计数器加一
                cnt += 1
            elif:
                cnt = 1   
            if cnt == maxcnt:    # 如果当前元素的计数器等于目前的最大次数,把该元素加入res
                res.append(lst[i])
            if cnt > maxcnt:   # 如果当前元素的计数器大于目前最大次数,res更新为当前元素
                maxcnt = cnt
                res = [lst[i]]
            pre = lst[i]
        return res

判定完美数:又又又一次写的代码超时了。。。为什么别人的脑子这么好用www

完美数: 2^{p-1}2^{p}-1 且 p 和 2p−1 都为质数

class Solution:
    def checkPerfectNumber(self, num: int) -> bool:
        ans = 1
        x = 2
        y = 2
        while y > 1:
            if num % x == 0:
                ans += x
            x += 1
            y = num // x
        if ans == num:
            return True
        if ans != num:
            return False
class Solution:
    def checkPerfectNumber(self, num: int) -> bool:
        def isPrime(x):
            for j in range(2, x//2):
                if not x % j:
                    return False
            return x > 1
        p = 1
        while not num //2 :
            num //= 2
            p += 1
        return num + 1 == pow(2,p) and isPrime(x) and isPrime(p)

Dataframe的一些操作数:

dt.sort_values(by='colunms_name')  对指定列按照升序排列

dt.groupby(['colunms_name)']) 按照指定列对数据分组

dt['colunms__name'].first().reset_index()  first 函数返回指定列每个分组中的第一个非缺失值,reset重置索引

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值