面试150,数组 / 字符串

27. 移除元素

在这里插入图片描述

class Solution:
    def removeElement(self, nums: List[int], val: int) -> int:
        # 把不等于 val 的值移动到前面
        n = len(nums)
        left = 0

        for right in range(n):
            if nums[right] != val:
                nums[left] = nums[right]
                left += 1
        return left

26. 删除有序数组中的重复项

在这里插入图片描述

只保留 1 个元素

class Solution:
    def removeDuplicates(self, nums: List[int]) -> int:
        n = len(nums) 

        left = 0  # 指向有效数组的最后一个元素
        # right 遍历数组, 每次与有效数组最后一个元素比较是否相同
        for right in range(n):
            if nums[right] != nums[left]:
                left += 1
                nums[left] = nums[right]
        return left + 1

80. 删除有序数组中的重复项 II

在这里插入图片描述
保留 k 个元素,次数 k = 2

class Solution:
    def removeDuplicates(self, nums: List[int]) -> int:
        n = len(nums)
        left = 0  # 指向有效数组的后一个位置
        k = 2  # 保留两个
        for right in range(n):
            if left < k or nums[right] != nums[left-k]:
                nums[left] = nums[right]
                left += 1
        return left

274. H 指数

在这里插入图片描述
一般的情况下

class Solution:
    def hIndex(self, citations: List[int]) -> int:
        n = len(citations)
        cnt = [0] * (n + 1)  # cnt[i] 引用次数 >= i 的数目

        for v in citations:
            cite = min(v, n)  # 引用次数大于 n 的情况, 算作n
            cnt[cite] += 1
        
        s = 0
        for i in range(n, -1, -1):
            s += cnt[i]  # 引用次数>=i的数量
            if s >= i:
                return i


有序的情况下

class Solution:
    def hIndex(self, citations: List[int]) -> int:
        # 有h篇论文的cite次数>=h
        n = len(citations)
        citations.sort()
        ans = 0

        for i, v in enumerate(citations):
            d = n - i + 1  # 剩余文章数
            if v >= d:
                return d

380. O(1) 时间插入、删除和获取随机元素

在这里插入图片描述
list 删除尾元素的速度为 O(1)
所以删除的时候,可以将待删除的值与末尾元素交换,然后删除末尾元素

from random import choice
class RandomizedSet:
    def __init__(self):
        self.nums = []
        self.indices = {}  # { val: 在nums中的下标 }

    def insert(self, val: int) -> bool:
        if val in self.indices:
            return False
        # 如果不在, 则在末尾插入元素
        self.indices[val] = len(self.nums)
        self.nums.append(val)
        return True

    def remove(self, val: int) -> bool:
        if val not in self.indices:
            return False
        id = self.indices[val]  # val在nums中的下标
        # 1.将末尾元素与待删除元素的位置交换
        self.nums[id] = self.nums[-1]  # 将末尾元素的值移动到当前val位置
        self.indices[self.nums[id]] = id  # 更新对应的id
        # 删除 val
        self.nums.pop()
        del self.indices[val]
        return True

    def getRandom(self) -> int:
        return choice(self.nums)

134. 加油站

在这里插入图片描述
“已经在谷底了,怎么走都是向上。”

下图为,从 0 加油站出发,到达每个站时的油量变化
可以看出,当走到 3 号加油站时,油量达到最低
在这里插入图片描述
所以从该点出发,之后的油量都不会比当前还低

在这里插入图片描述

同时,判断 sum(gas)sum(cost) 的大小关系

  • 如果 sum(gas) >= sum(cost) ,则一定有解
  • 反之没有,返回 -1
class Solution:
    def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int:
        # 先计算从 0 号加油站出发的油量变化,然后从中找到油量最低时所处的加油站
        ans = 0
        min_s = 0  # 表示从 0 出发遇到的最小油量点
        s = 0

        for i, (g, c) in enumerate(zip(gas, cost)):
            s += g - c  # 在 i 处加油,然后出发从 i 到 i+1
            if s < min_s:
                min_s = s  # 更新最小油量
                ans = i + 1  # 注意 s 减去 c 之后,汽车在 i+1 而不是 i

        # 循环结束后,s 即为 gas 之和减去 cost 之和
        if s < 0:  # 说明不存在可行解
            return -1
        else:
            return ans

13. 罗马数字转整数

在这里插入图片描述

class Solution:
    def romanToInt(self, s: str) -> int:
        # 小数在前表示<减去>, 小数在后表示<加上>
        # 从后往前遍历, 判断当前数是否比上一个数大
        # 如果大于上一个数, 则直接加, 反之用减

        d = {
            'I':1,
            'V':5,
            'X':10,
            'L':50,
            'C':100,
            'D':500,
            'M':1000
        }

        s = s[::-1]
        last_val = 0
        ans = 0

        for c in s:
            v = d[c]
            if v >= last_val:
                ans += v
            else:
                ans -= v
            last_val = v
        
        return ans

12. 整数转罗马数字

在这里插入图片描述

class Solution:
    def intToRoman(self, num: int) -> str:
        hashmap = {
            1000:'M', 900:'CM', 
            500:'D', 400:'CD',
            100:'C', 90:'XC',
            50:'L', 40:'XL', 
            10:'X', 9:'IX', 
            5:'V', 4:'IV', 1:'I'}

        ans = ''

        for key in hashmap:
            if num // key != 0:
                count = num // key
                ans += hashmap[key] * count
                num %= key
        
        return ans

58. 最后一个单词的长度

在这里插入图片描述

class Solution:
    def lengthOfLastWord(self, s: str) -> int:
        i = len(s) - 1
        # 去掉空格
        while i >= 0 and s[i] == ' ':
            i -= 1
        
        # 遍历最后一个str的长度
        ans = 0
        while i >= 0 and s[i] != ' ':
            i -= 1
            ans += 1
        
        return ans

14. 最长公共前缀

在这里插入图片描述

list中字符串的最大或最小长度
min_l = min(map(len, strs), default=0)

class Solution:
    def longestCommonPrefix(self, strs: List[str]) -> str:
        n = len(strs)
        min_l = min(map(len, strs), default=0)
        j = 0
        cur = ''
        ans = ''

        while j < min_l:
            for i in range(n):
                if i == 0:
                    cur = strs[i][j]
                elif cur != strs[i][j]:
                    return ans
            j += 1
            ans += cur
            cur = ''
        return ans

151. 反转字符串中的单词

在这里插入图片描述

class Solution:
    def reverseWords(self, s: str) -> str:
        s = s.strip()
        res = []
        n = len(s)
        i, j = n-1, n-1

        # 从后往前
        while i >= 0:
            if s[i] != ' ':
                i -= 1
            else:
                # s[i] == ' '
                res.append(s[i+1 : j+1])
                while i >= 0 and s[i] == ' ':
                    i -= 1
                j = i

        # 开头第一个字符串
        res.append(s[ : j+1])
        return ' '.join(res)

28. 找出字符串中第一个匹配项的下标

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

6. Z 字形变换

注意特殊情况
if numRows < 2: return s

class Solution:
    def convert(self, s: str, numRows: int) -> str:
        if numRows < 2:
            return s
            
        n = len(s)
        res = ['' for _ in range(numRows)]

        flag = -1
        i = 0

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值