LeetCode——难度等级Easy的前40~50道题(题号191~231)

目录

191.位1的个数 number-of-1-bits

198.打家劫舍 house-robber

202.快乐数 happy-number

203.移除链表元素 remove-linked-list-elements

204.计数质数 count-primes

205 同构字符串 isomorphic-strings

206.反转链表 reverse-linked-list

217.存在重复元素 contains-duplicate

218.存在重复元素II contains-duplicate-ii

231.2的幂 power-of-two


191.位1的个数 number-of-1-bits

"""
编写一个函数,输入是一个无符号整数,返回其二进制表达式中数字位数为 ‘1’ 的个数(也被称为汉明重量)。

 

示例 1:

输入:00000000000000000000000000001011
输出:3
解释:输入的二进制串 00000000000000000000000000001011 中,共有三位为 '1'。
示例 2:

输入:00000000000000000000000010000000
输出:1
解释:输入的二进制串 00000000000000000000000010000000 中,共有一位为 '1'。
示例 3:

输入:11111111111111111111111111111101
输出:31
解释:输入的二进制串 11111111111111111111111111111101 中,共有 31 位为 '1'。
 

提示:

请注意,在某些语言(如 Java)中,没有无符号整数类型。在这种情况下,输入和输出都将被指定为有符号整数类型,并且不应影响您的实现,因为无论整数是有符号的还是无符号的,其内部的二进制表示形式都是相同的。
在 Java 中,编译器使用二进制补码记法来表示有符号整数。因此,在上面的 示例 3 中,输入表示有符号整数 -3。
"""


def hammingWeight(n):
    return bin(n).count('1')


a = 3
b = hammingWeight(a)
print(b)

198.打家劫舍 house-robber

"""
你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。

给定一个代表每个房屋存放金额的非负整数数组,计算你在不触动警报装置的情况下,能够偷窃到的最高金额。

示例 1:

输入: [1,2,3,1]
输出: 4
解释: 偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。
     偷窃到的最高金额 = 1 + 3 = 4 。
示例 2:

输入: [2,7,9,3,1]
输出: 12
解释: 偷窃 1 号房屋 (金额 = 2), 偷窃 3 号房屋 (金额 = 9),接着偷窃 5 号房屋 (金额 = 1)。
     偷窃到的最高金额 = 2 + 9 + 1 = 12 。
"""


def rob1(nums):
    if len(nums) == 0:
        return 0
    if len(nums) <= 2:
        return max(nums)
    dp = [0 for i in range(0, 2)]
    dp[0] = nums[0]
    dp[1] = max(nums[1], nums[0])
    for i in range(2, len(nums)):
        dp[i % 2] = max(dp[(i - 1) % 2], dp[(i - 2) % 2] + nums[i])
    return dp[(len(nums) - 1) % 2]


def rob2(nums):
    last = 0
    now = 0
    for i in nums:
        last, now = now, max(last+i, now)
    return now


def rob3(nums):
    n = len(nums)
    if n == 0:
        return 0
    dp = [0] * (n+1)
    dp[1] = nums[0]
    for i in range(1, n):
        dp[i+1] = max(dp[i], dp[i-1]+nums[i])
    return dp[n]


def rob4(nums):
    nums = [0] * 3 + nums
    for i in range(3, len(nums)):
        nums[i] += max(nums[i - 2], nums[i - 3])
    return max(nums[-1], nums[-2])


a = [2, 7, 9, 3, 1]
b = rob2(a)
print(b)

202.快乐数 happy-number

"""
编写一个算法来判断一个数是不是“快乐数”。

一个“快乐数”定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1,也可能是无限循环但始终变不到 1。如果可以变为 1,那么这个数就是快乐数。

示例:

输入: 19
输出: true
解释:
1^2 + 9^2 = 82
8^2 + 2^2 = 68
6^2 + 8^2 = 100
1^2 + 0^2 + 0^2 = 1
"""


def isHappy1(n: int) -> bool:
    record = {}
    sq_sum = 0
    while n != 1:
        sq_sum = 0
        sub_num = n
        while sub_num > 0:
            sq_sum += (sub_num % 10) * (sub_num % 10)
            sub_num //= 10
        if sq_sum in record:
            return False
        else:
            record[sq_sum] = 1
        n = sq_sum
    return True


def isHappy2(n: int) -> bool:
    result = 0
    while result != 1 and result != 4:
        result = 0
        n = str(n)
        for i in n:
            result += int(i) ** 2
        n = result
    if result == 1:
        return True
    return False



a = 19
print(isHappy2(a))

203.移除链表元素 remove-linked-list-elements

"""
删除链表中等于给定值 val 的所有节点。

示例:

输入: 1->2->6->3->4->5->6, val = 6
输出: 1->2->3->4->5
"""

import linklist
from linklist import ListNode


def removeElements(head, val):
    dummy = ListNode(-1)
    dummy.next = head
    p = dummy
    while p.next:
        if p.next.val == val:
            p.next = p.next.next
        else:
            p = p.next
    return dummy.next


def removeElements2(head, val):
    while head is not None and head.val == val:
        head = head.next
    current = head
    while current:
        if current.next and current.next.val == val:
            current.next = current.next.next
        else:
            current = current.next
    return head


link = linklist.LinkList()
link.initList([1, 2, 6, 3, 4, 5, 6])
print(link)
removeElements(link.head, 6)
print(link)

204.计数质数 count-primes

"""
统计所有小于非负整数 n 的质数的数量。

示例:

输入: 10
输出: 4
解释: 小于 10 的质数一共有 4 个, 它们是 2, 3, 5, 7 。
"""


def countPrimes(n: int) -> int:
    if n < 3:
        return 0
    prime = [1] * n
    prime[0] = prime[1] = 0
    for i in range(2, int(n**0.5) + 1):
        if prime[i] == 1:
            prime[i*i:n:i] = [0]*len(prime[i*i:n:i])
    return sum(prime)


def countPrimes2(n: int) -> int:
    def helper(n, dp):
        for i in range(2, n):
            if dp[i] == 1:
                k = i * i
                if k >= n:
                    return
                while k < n:
                    dp[k] = 0
                    k += i
    if n < 2:
        return 0
    dp = [1] * n
    dp[0] = 0
    dp[1] = 0
    helper(n, dp)
    # for i in xrange(0, n):
    #     if dp[i] == 1:
    #         print i + 1

    return sum(dp)


a = countPrimes(10)
print(a)

205 同构字符串 isomorphic-strings

"""
给定两个字符串 s 和 t,判断它们是否是同构的。

如果 s 中的字符可以被替换得到 t ,那么这两个字符串是同构的。

所有出现的字符都必须用另一个字符替换,同时保留字符的顺序。两个字符不能映射到同一个字符上,但字符可以映射自己本身。

示例 1:

输入: s = "egg", t = "add"
输出: true
示例 2:

输入: s = "foo", t = "bar"
输出: false
示例 3:

输入: s = "paper", t = "title"
输出: true
说明:
你可以假设 s 和 t 具有相同的长度。
"""


def isIsomorphic(s: str, t: str) -> bool:
    return len(set(s)) == len(set(t)) == len(set(zip(s, t)))


def isIsomorphic2(s: str, t: str) -> bool:
    dic1 = {}
    dic2 = {}
    for key, value in zip(s, t):
        if key not in dic1:
            dic1[key] = value
        if value not in dic2:
            dic2[value] = key
        if dic1[key] != value or dic2[value] != key:
            return False
    return True


s = "foo"
t = "bar"
c = isIsomorphic(s, t)
print(c)

206.反转链表 reverse-linked-list

"""
反转一个单链表。

示例:

输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
进阶:
你可以迭代或递归地反转链表。你能否用两种方法解决这道题?
"""
import linklist


def reverseList(head):
    cur, prev = head, None
    while cur:
        cur.next, prev, cur = prev, cur, cur.next
    return prev


link = linklist.LinkList()
link2 = linklist.LinkList()
link.initList([1, 2, 3, 4, 5])
print(link)
link2 = reverseList(link.head)
linklist.printLink(link2)

217.存在重复元素 contains-duplicate

"""
给定一个整数数组,判断是否存在重复元素。

如果任何值在数组中出现至少两次,函数返回 true。如果数组中每个元素都不相同,则返回 false。

示例 1:

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

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

输入: [1,1,1,3,3,4,3,2,4,2]
输出: true
"""


def containsDuplicate(nums) -> bool:
    return len(set(nums)) != len(nums)


a = [1, 2, 3, 1]
b = containsDuplicate(a)
print(b)

218.存在重复元素II contains-duplicate-ii

"""
给定一个整数数组和一个整数 k,判断数组中是否存在两个不同的索引 i 和 j,使得 nums [i] = nums [j],并且 i 和 j 的差的绝对值最大为 k。

示例 1:

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

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

输入: nums = [1,2,3,1,2,3], k = 2
输出: false
"""
from collections import deque


def containsNearbyDuplicate(nums, k):
    if not nums:
        return False
    if k == 0:
        return False
    k = k + 1
    k = min(k, len(nums))

    window = deque([])
    d = set()
    for i in range(0, k):
        if nums[i] in d:
            return True
        d |= {nums[i]}
        window.append(i)
    for i in range(k, len(nums)):
        d -= {nums[window.popleft()]}
        if nums[i] in d:
            return True
        d |= {nums[i]}
        window.append(i)
    return False


def containsNearbyDuplicate2(nums, k):
    d = dict()
    for i, v in enumerate(nums):
        if v in d.keys():
            if i-d[v] <= k:
                return True
        d[v] = i
    return False


def containsNearbyDuplicate3(nums, k):
    record = {}
    for i in range(len(nums)):
        if nums[i] in record:
            return True
        record[nums[i]] = 0
        if len(record) == k+1:
            record.pop(nums[i-k])
    return False


a = containsNearbyDuplicate([1, 0, 1, 1], 1)
print(a)

231.2的幂 power-of-two

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

示例 1:

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

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

输入: 218
输出: false

"""


def isPowerOfTwo(n: int) -> bool:
    if n < 2:
        return False
    m = 0
    while m == 0:
        n, m = divmod(n, 2)
    if n == 0:
        return True
    else:
        return False


def isPowerOfTwo2(n: int) -> bool:
    """
    64  = 00000000 00000000 00000000 01000000
    -64 = 10000000 00000000 00000000 01000000
    反码 = 11111111 11111111 11111111 10111111
    补码 = 11111111 11111111 11111111 11000000
    求并 = 00000000 00000000 00000000 01000000 = 64
    65  = 00000000 00000000 00000000 01000001
    -65 = 10000000 00000000 00000000 01000001
    反码 = 11111111 11111111 11111111 10111110
    补码 = 11111111 11111111 11111111 10111111
    求并 = 00000000 00000000 00000000 00000001 = 1
    """
    return n != 0 and (n & -n) == n
    # return n > 0 and not (n & (n - 1))


a = 64
b = isPowerOfTwo2(a)
print(b)

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值