LeetCode——难度等级Easy的前50~60道题(题号242~326)

目录

242.有效的字母异位词 valid-anagram

258.各位相加 add-digits

263.丑数 ugly-number

268.缺失数字 missing-number

278.第一个错误版本 first-bad-version

283.移动零 move-zeroes

290.单词模式 word-pattern

292.Nim游戏 nim-game

303.区域检索-数组不可变 range-sum-query-immutable

326.3的幂 power-of-three


242.有效的字母异位词 valid-anagram

"""
给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的一个字母异位词。

示例 1:

输入: s = "anagram", t = "nagaram"
输出: true
示例 2:

输入: s = "rat", t = "car"
输出: false
说明:
你可以假设字符串只包含小写字母。

进阶:
如果输入字符串包含 unicode 字符怎么办?你能否调整你的解法来应对这种情况?
"""


def isAnagram(s: str, t: str) -> bool:
    if len(s) != len(t):
        return False
    
    chars = set(s)
    for char in chars:
        if s.count(char) != t.count(char):
            return False
    return True


def isAnagram2(s: str, t: str) -> bool:
    from collections import Counter
    return Counter(s) == Counter(t)


def isAnagram3(s: str, t: str) -> bool:
    if not len(s) == len(t):
        return False

    sHash = tHash = 1
    sCount = [0] * 26
    tCount = [0] * 26
    p1 = 2903
    p2 = 29947
    for i in range(0, len(s)):
        sCount[ord(s[i]) - ord('a')] += 1
        tCount[ord(t[i]) - ord('a')] += 1

    for i in range(0, 26):
        sHash = sHash * p1 + sCount[i]
        tHash = tHash * p1 + tCount[i]
        p1 *= p2
    return sHash == tHash


def isAnagram4(s: str, t: str) -> bool:
    if len(s) != len(t):
        return False
    dic = dict()
    for i in s:
        if i in dic:
            dic[i] += 1
        else:
            dic[i] = 1
    
    for i in t:
        if i in dic:
            dic[i] -= 1
        else:
            dic[i] = -1
    
    for i in dic:
        if dic[i] != 0:
            return False
    return True


s = "anagram"
t = "nagaram"
a = isAnagram(s, t)
print(a)

258.各位相加 add-digits

"""
给定一个非负整数 num,反复将各个位上的数字相加,直到结果为一位数。

示例:

输入: 38
输出: 2
解释: 各位相加的过程为:3 + 8 = 11, 1 + 1 = 2。 由于 2 是一位数,所以返回 2。
进阶:
你可以不使用循环或者递归,且在 O(1) 时间复杂度内解决这个问题吗?
"""


def addDigits(num: int) -> int:
    while num > 9:
        num = eval('+'.join(list(str(num))))
    return num


def addDigits2(num: int) -> int:
    """
    n = 100a + 10b + c
      = 99a + 9b + (a + b + c) , 设(a + b + c) = 10d + e
      = 99a + 9b + 9d + d + e , d+e最小为1
      可以看出来结果就是n%9, 但是当n是9的倍数就不成立了
      所以先从n中取出1作为最小结果再对9取余
    n = (n - 1) + 1, 对n-1拆分
      = [99a + 9b + (a + b + c)] + 1 , 设(a + b + c) = 10d + e
      = [99a + 9b + 9d + d + e] + 1 , d+e最小为1
      结果就是(n-1)%9+1
    """
    if num < 10:
        return num
    return 1 + (num - 1) % 9


class Solution:
    def addDigits3(self, num: int) -> int:
        """递归"""
        sum = 0
        if not num:
            return sum
        while num:
            sum += num % 10
            num = num // 10
        if sum > 9:
            return self.addDigits(sum)
        return sum



b = addDigits(38822222)
print(b)

263.丑数 ugly-number

"""
编写一个程序判断给定的数是否为丑数。

丑数就是只包含质因数 2, 3, 5 的正整数。

示例 1:

输入: 6
输出: true
解释: 6 = 2 × 3
示例 2:

输入: 8
输出: true
解释: 8 = 2 × 2 × 2
示例 3:

输入: 14
输出
解释: 14 不是丑数,因为它包含了另外一个质因数 7。
说明:

1 是丑数。
输入不会超过 32 位有符号整数的范围: [−2^31,  2^31 − 1]。

"""


def isUgly(num: int) -> bool:
    if num <= 0:
        return False
    
    while num % 2 == 0 or num % 3 == 0 or num % 5 == 0:
        if num % 2 == 0:
            num /= 2
        if num % 3 == 0:
            num /= 3
        if num % 5 == 0:
            num /= 5
    if num == 1:
        return True
    return False


b = isUgly(5)
print(b)

268.缺失数字 missing-number

"""
给定一个包含 0, 1, 2, ..., n 中 n 个数的序列,找出 0 .. n 中没有出现在序列中的那个数。

示例 1:

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

输入: [9,6,4,2,3,5,7,0,1]
输出: 8
说明:
你的算法应具有线性时间复杂度。你能否仅使用额外常数空间来实现?

"""


def missingNumber(nums):
    n = len(nums)
    s = n*(n+1)//2
    return s - sum(nums)


a = [9, 6, 4, 2, 3, 5, 7, 0, 1]
b = missingNumber(a)
print(b)

278.第一个错误版本 first-bad-version

"""
你是产品经理,目前正在带领一个团队开发新的产品。不幸的是,你的产品的最新版本没有通过质量检测。由于每个版本都是基于之前的版本开发的,所以错误的版本之后的所有版本都是错的。

假设你有 n 个版本 [1, 2, ..., n],你想找出导致之后所有版本出错的第一个错误的版本。

你可以通过调用 bool isBadVersion(version) 接口来判断版本号 version 是否在单元测试中出错。实现一个函数来查找第一个错误的版本。你应该尽量减少对调用 API 的次数。

示例:

给定 n = 5,并且 version = 4 是第一个错误的版本。

调用 isBadVersion(3) -> false
调用 isBadVersion(5) -> true
调用 isBadVersion(4) -> true

所以,4 是第一个错误的版本。
"""
# The isBadVersion API is already defined for you.
# @param version, an integer
# @return a bool


def isBadVersion(version):
    return version > 26


def firstBadVersion(n):
    """
    [0000000|0011111]
    [0000000|0011|111]
    [0000000|00|11|111]
    [0000000|00|1|1|111]
    """
    low = 1
    high = n
    while low < high:
        mid = low + (high - low) // 2
        if isBadVersion(mid):
            high = mid
        else:
            low = mid + 1
    return low


a = firstBadVersion(40)
print(a)

283.移动零 move-zeroes

"""
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

示例:

输入: [0,1,0,3,12]
输出: [1,3,12,0,0]
说明:

必须在原数组上操作,不能拷贝额外的数组。
尽量减少操作次数。
"""


def moveZeroes(nums):
    """
    如果不是0,就按顺序移到列表前面
    """
    i = j = 0
    for i in range(len(nums)):
        if nums[i] != 0:
            nums[j], nums[i] = nums[i], nums[j]
            j += 1


a = [0, 1, 0, 3, 12]
moveZeroes(a)
print(a)

290.单词模式 word-pattern

"""
给定一种 pattern(模式) 和一个字符串 str ,判断 str 是否遵循相同的模式。

这里的遵循指完全匹配,例如, pattern 里的每个字母和字符串 str 中的每个非空单词之间存在着双向连接的对应模式。

示例1:

输入: pattern = "abba", str = "dog cat cat dog"
输出: true
示例 2:

输入:pattern = "abba", str = "dog cat cat fish"
输出: false
示例 3:

输入: pattern = "aaaa", str = "dog cat cat dog"
输出: false
示例 4:

输入: pattern = "abba", str = "dog dog dog dog"
输出: false
说明:
你可以假设 pattern 只包含小写字母, str 包含了由单个空格分隔的小写字母。
"""


def wordPattern(pattern: str, str: str) -> bool:
    p = [i for i in pattern]
    s = str.split(' ')
    if len(pattern) != len(s):
        return False
    if len(set(p)) != len(set(s)):
        return False
    z = zip(p, s)
    if len(set(z)) == len(set(p)):
        return True
    else:
        return False


def wordPattern2(pattern: str, str: str) -> bool:
    d1, d2 = {}, {}
    for i, v in enumerate(pattern):
        d1[v] = d1.get(v, []) + [i]
    for i, v in enumerate(str.split()):
        d2[v] = d2.get(v, []) + [i]
    return list(d1.values()) == list(d2.values())


def wordPattern3(pattern: str, str: str) -> bool:
    str = str.split()
    a = zip(pattern, str)
    return len(pattern) == len(str) and len(set(a)) == len(set(pattern)) == len(set(str))


a = wordPattern(pattern="abba", str="dog cat dog cat")
print(a)

292.Nim游戏 nim-game

"""
你和你的朋友,两个人一起玩 Nim游戏:桌子上有一堆石头,每次你们轮流拿掉 1 - 3 块石头。 拿掉最后一块石头的人就是获胜者。你作为先手。

你们是聪明人,每一步都是最优解。 编写一个函数,来判断你是否可以在给定石头数量的情况下赢得游戏。

示例:

输入: 4
输出: false
解释: 如果堆中有 4 块石头,那么你永远不会赢得比赛;
     因为无论你拿走 1 块、2 块 还是 3 块石头,最后一块石头总是会被你的朋友拿走。
"""


def canWinNim(n: int) -> bool:
    return n % 4 != 0

303.区域检索-数组不可变 range-sum-query-immutable

'''
给定一个整数数组  nums,求出数组从索引 i 到 j  (i ≤ j) 范围内元素的总和,包含 i,  j 两点。

示例:

给定 nums = [-2, 0, 3, -5, 2, -1],求和函数为 sumRange()

sumRange(0, 2) -> 1
sumRange(2, 5) -> -1
sumRange(0, 5) -> -3
说明:

你可以假设数组不可变。
会多次调用 sumRange 方法。
'''


class NumArray2(object):
    def __init__(self, nums):
        """
        initialize your data structure here.
        :type nums: List[int]
        """
        self.dp = [0] * (len(nums) + 1)
        for i in range(0, len(nums)):
            self.dp[i + 1] = self.dp[i] + nums[i]
        

    def sumRange(self, i, j):
        """
        sum of elements nums[i..j], inclusive.
        :type i: int
        :type j: int
        :rtype: int
        """
        return self.dp[j + 1] - self.dp[i]


class NumArray:
    def __init__(self, nums):
        self.nums = nums

    def sumRange(self, i: int, j: int) -> int:
        return sum(self.nums[i:j+1])


# Your NumArray object will be instantiated and called as such:
nums = [-2, 0, 3, -5, 2, -1]
obj = NumArray(nums)
param_1 = obj.sumRange(2, 3)
print(param_1)

326.3的幂 power-of-three

'''
给定一个整数,写一个函数来判断它是否是 3 的幂次方。

示例 1:

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

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

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

输入: 45
输出: false
进阶:
你能不使用循环或者递归来完成本题吗?
'''


def isPowerOfThree(n: int):
    if n > 0:
        return (1162261467 % n) == 0
    else:
        return False


print(isPowerOfThree(27))

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值