力扣刷题_数组_位运算

文章目录

  • 时间复杂度
    • 字典
    • list
  • 知识点
    • 位运算
  • 字符串/数组
    • easy
      • 1
        • LeetCode-python
        • LeetCode-python 219. 存在重复元素 II
        • LeetCode-python 167. 两数之和 II - 输入有序数组
        • LeetCode-python 344.反转字符串
        • LeetCode-python 697. 数组的度
        • LeetCode-python 922. 按奇偶排序数组 II
        • LeetCode-python 977.有序数组的平方
        • 剑指 Offer 63. 股票的最大利润
        • 121. 买卖股票的最佳时机
        • LeetCode-python 1331. 数组序号转换
        • LeetCode-python 面试题 17.10. 主要元素
        • LeetCode-python 剑指Offer 04. 二维数组中的查找
      • 2
        • Leetcode-python 1550. 存在连续三个奇数的数组
        • LeetCode-python 88. 合并两个有序数组
      • 3
        • LeetCode-python 628. 三个数的最大乘积
        • Leetcode-python1588.所有奇数长度子阵列的和
        • 牛客 有序数组的平方种类数
    • media
    • hard
      • 面试题 17.21. 直方图的水量
  • 位运算
    • easy
        • Leetcode-python 面试题 17.04. 消失的数字
      • 1
        • Leetcode-python 剑指 Offer 15. 二进制中1的个数
        • Leetcode-python 136. 只出现一次的数字
        • eetcode-python 762. 二进制表示中质数个计算置位
        • Leetcode-python 389. 找不同
        • Leetcode-python 461. 汉明距离
      • 3
        • Leetcode-python 169. 多数元素
        • Leetcode-python 231. 2的幂
        • Leetcode-python 268. 丢失的数字
        • Leetcode-python 1342. 将数字变成0的操作次数
        • Leetcode-python 1290. 二进制链表转整数
        • Leetcode-python 371. 两整数之和
        • Leetcode-python 405. 数字转换为十六进制数
    • media
    • hard

又开始刷题了,以前刷Java版的,现在开始python的了。仅作为自己总结,便于回顾。

时间复杂度

字典

字典内置操作时间复杂度:
copy O(n)
get item O(1)
set item O(1)
delete item O(1)
in O(1)
遍历 O(n)

list

列表内置函数时间复杂度:
index[]索引 O(1)
index[]索引修改 O(1)
append O(1)
pop O(1)
pop(i) O(n)
insert(i,item) O(n)
del operator O(n)
in O(n)
get slice[x:y] O(k)(k是X到Y的长度)
del slice O(n)
set slice O(n+k)(相当于先删除,在加进去)

例子:
list1 = [1,2,3,4,5,56]
list1[0:3] = [77,777,7777,7,2,7,7,27]
>>>[77, 777, 7777, 7, 2, 7, 7, 27, 4, 5, 56]

reverse(逆序) O(n)
concatenate(把第二个列表里的内容加到第一个队尾) O(k)(第二个列表里有k各元素)
sort O(nlogn)
multiply(乘法) O(nk)

知识点

位运算

位操作:一般是将数字化为二进制数后进行操作。
& 与 两个位都为1时,结果才为1 (统计奇数) 全1为1
| 或 两个位都为0时,结果才为0 (统计偶数) 全0为0
^ 异或 两个位相同为0,相异为1 (常用统计不相同数) 不同为1
~ 取反 0变1,1变0
<<左移 各二进位全部左移若干位,高位丢弃,低位补0
位运算>>右移 各二进位全部右移若干位,对无符号数,高位补0,有符号数,各编译器处理方法不一样,有的补符号位(算术右移),有的补0(逻辑右移)
用法:
1)判断奇偶 (二进制数以1结尾是奇数,以0结尾是偶数)
for i in range(100): #打印所有奇数
if i&1==1:
print(i)
2)消去最后一位1
x & (x - 1)
3)找出出现一次的数
a ^ b ^ b = a

字符串/数组

easy

1

LeetCode-python

题目链接
难度:简单 类型: 数组
题目:
解题思路:。
时间复杂度:
空间复杂度:

LeetCode-python 219. 存在重复元素 II

题目链接
难度:简单 1 类型: 数组
解题思路:可以借用字典。

    def containsNearbyDuplicate(self, nums: List[int], k: int) -> bool:
        nums_dic={
     }
        for index, name in enumerate(nums):
            if name not in nums_dic:
                nums_dic[name]=index
            else:
                if index-nums_dic[name]<=k:
                    return True
                else:nums_dic[name]=index
        return False

LeetCode-python 167. 两数之和 II - 输入有序数组

题目链接
难度:简单 1 类型: 数组
解题思路:可以借用字典。

LeetCode-python 344.反转字符串

题目链接
难度:简单 1 类型: 数组
题目:编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 char[] 的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
你可以假设数组中的所有字符都是 ASCII 码表中的可打印字符。

示例 1:
输入:["h","e","l","l","o"]
输出:["o","l","l","e","h"]
示例 2:
输入:["H","a","n","n","a","h"]
输出:["h","a","n","n","a","H"]

解题思路:双指针,start指向头,end指向尾,两个指针指向的元素交换,之后start加1,end减1,继续交换。

# 1
s_len=len(s)
for i in range(int(s_len/2)):
    s[i],s[s_len-i-1]=s[s_len-i-1],s[i]
# 2
'''
start = 0
end = int(len(s)-1)
while start
# 3
'''
s_len=len(s)
for i in range(int(s_len/2)):
    temp=s[i]
    s[i]=s[s_len-i-1]
    s[s_len-i-1]=temp
   '''

三段小代码,代码1/2执行时间较短,1/2/3内存消耗一样。

LeetCode-python 697. 数组的度

题目链接
难度:简单 1 类型: 数组

LeetCode-python 922. 按奇偶排序数组 II

题目链接
难度:简单 1 类型: 数组

LeetCode-python 977.有序数组的平方

题目链接
难度:简单 1 类型: 数组
题目:给定一个按非递减顺序排序的整数数组 A,返回每个数字的平方组成的新数组,要求也按非递减顺序排序。

class Solution(object):
    def sortedSquares(self, A):
        return sorted([x*x for x in A])

剑指 Offer 63. 股票的最大利润

题目链接
难度:简单 1 类型: 数组
解题思路:最大储水量一个思路。

121. 买卖股票的最佳时机

题目链接
难度:简单 1 类型: 数组
解题思路:最大储水量一个思路。

LeetCode-python 1331. 数组序号转换

题目链接
难度:简单 1 类型: 数组
解题思路:借用字典。

LeetCode-python 面试题 17.10. 主要元素

题目链接
难度:简单 1 类型: 数组
解题思路:借用字典。

LeetCode-python 剑指Offer 04. 二维数组中的查找

题目链接
难度:简单 1 类型: 数组
解题思路:使用二分查找法。

2

Leetcode-python 1550. 存在连续三个奇数的数组

题目链接
难度:简单 2 类型: 数组
解题思路:三个数的和是奇数,两个数的和是偶数。

class Solution:
    def threeConsecutiveOdds(self, arr: List[int]) -> bool:
        flag=False
        for i in range(len(arr)-2):
            if arr[i]%2!=0:
                if sum(arr[i:i+3])%2!=0 and sum(arr[i:i+2])%2==0:
                    flag= True
                    break
        return flag

LeetCode-python 88. 合并两个有序数组

题目链接
难度:简单 2 类型: 数组
解题思路:1、从后往前,2、尽量使用while,3、注意事项是不用return。

 # 方法一
  i,j,k=m-1,n-1,m+n-1
  while i>=0 and j>=0:
      if nums1[i]<nums2[j]:
          nums1[k]=nums2[j]
          k-=1
          j-=1
      else:
          nums1[k]=nums1[i]
          k-=1
          i-=1
  if j>=0:
      while j>=0:
          nums1[k]=nums2[j]
          k-=1
          j-=1
          
 # 方法二
 for i in range(n):
     nums1[m+i]=nums2[i]
 nums1.sort()

3

LeetCode-python 628. 三个数的最大乘积

题目链接
难度:简单 3 类型: 数组
题目:给定一个整型数组,在数组中找出由三个数组成的最大乘积,并输出这个乘积。
解题思路:将数组进行升序排序,如果数组中所有的元素都是非负数,那么答案即为最后三个元素的乘积。

如果数组中出现了负数,那么我们还需要考虑乘积中包含负数的情况,显然选择最小的两个负数和最大的一个正数是最优的,即为前两个元素与最后一个元素的乘积。

上述两个结果中的较大值就是答案。注意我们可以不用判断数组中到底有没有正数,0 或者负数,因为上述两个结果实际上已经包含了所有情况,最大值一定在其中。

class Solution:
    def maximumProduct(self, nums: List[int]) -> int:
		nums.sort()
		return max(nums[-3]*nums[-2]*nums[-1],nums[0]*nums[1]*nums[-1])

Leetcode-python1588.所有奇数长度子阵列的和

难度:简单 3 类型: 数组

牛客 有序数组的平方种类数

难度:简单 3 类型: 数组
题目:给定一个按非递减顺序排序的整数数组 A,返回每个数字的平方后有几种不同的数。

class Solution(object):
    def sortedSquares(self, A):
        return sorted([x*x for x in A])

media

hard

面试题 17.21. 直方图的水量

题目链接
难度:困难 类型: 数组
题目:给定一个直方图(也称柱状图),假设有人从上面源源不断地倒水,最后直方图能存多少水量?直方图的宽度为 1。
力扣刷题_数组_位运算_第1张图片
上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的直方图,在这种情况下,可以接 6 个单位的水(蓝色部分表示水)。

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

解题思路:算出每个坐标对应最高左右壁,减去自高即可。

class Solution:
    def trap(self, height: List[int]) -> int:
        if not height:
            return 0
        n = len(height)
        left, right = [0] * n, [0] * n
        left[0], right[-1] = height[0], height[-1]
        for i in range(1, n):
            left[i] = max(height[i], left[i - 1])
        for i in reversed(range(n - 1)):
            right[i] = max(height[i], right[i + 1])
        result = 0
        for i in range(n):
            result = result + min(left[i], right[i]) - height[i]
        return result
 # return sum(min(l, r) - h for l, r, h in zip(left, right, height)) 简洁写法,生成器

位运算

easy

Leetcode-python 面试题 17.04. 消失的数字

难度:简单 1 类型: 位运算
题目:数组nums包含从0到n的所有整数,但其中缺了一个。请编写代码找出那个缺失的整数。你有办法在O(n)时间内完成吗?
解题思路:求和;位运算。

class Solution:
    def missingNumber(self, nums: List[int]) -> int:
        n=len(nums)
        res=n
        for i in range(n):
            res^=i
            res^=nums[i]
        return res

1

Leetcode-python 剑指 Offer 15. 二进制中1的个数

难度:简单 1 类型: 位运算
题目:请实现一个函数,输入一个整数,输出该数二进制表示中 1 的个数。例如,把 9 表示成二进制是 1001,有 2 位是 1。因此,如果输入 9,则该函数输出 2。
解题思路:典型的位运算。

class Solution:
    def hammingWeight(self, n: int) -> int:
        res=0
        while n:
            if n&1==1:
                res+=1
            n>>=1
        return res 

Leetcode-python 136. 只出现一次的数字

难度:简单 1 类型: 位运算
题目:给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
解题思路:典型的位运算。

class Solution:
    def singleNumber(self, nums: List[int]) -> int:
        res=0
        for i in nums:
            res^=i
        return res

eetcode-python 762. 二进制表示中质数个计算置位

难度:简单 1 类型: 位运算
题目:给定两个整数 L 和 R ,找到闭区间 [L, R] 范围内,计算置位位数为质数的整数个数。(注意,计算置位代表二进制表示中1的个数。例如 21 的二进制表示 10101 有 3 个计算置位。还有,1 不是质数。)
解题思路:这里的质数可以枚举。

class Solution:
    def countPrimeSetBits(self, L: int, R: int) -> int:
        primes = {
     2, 3, 5, 7, 11, 13, 17, 19}
        return sum(bin(x).count('1') in primes for x in range(L, R+1))

Leetcode-python 389. 找不同

难度:简单 1 类型: 位运算
题目:给定两个字符串 s 和 t,它们只包含小写字母。
字符串 t 由字符串 s 随机重排,然后在随机位置添加一个字母。
请找出在 t 中被添加的字母。
解题思路:位运算,chr()获得数字s对应的字母,ord():获得字符s的ASCII值。

class Solution:
    def findTheDifference(self, s: str, t: str) -> str:
        res=0
        for i in s:
            res^=ord(i)
        for i in t:
            res^=ord(i)
        return chr(res)

Leetcode-python 461. 汉明距离

难度:简单 1 类型: 位运算
题目:两个整数之间的汉明距离指的是这两个数字对应二进制位不同的位置的数目。给出两个整数 x 和 y,计算它们之间的汉明距离。

class Solution:
    def hammingDistance(self, x: int, y: int) -> int:
        return bin(x^y).count('1')

3

Leetcode-python 169. 多数元素

难度:简单 3 类型: 多种方法
题目:给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。
解题思路
思路一:排序
如果将数组 nums 中的所有元素按照单调递增或单调递减的顺序排序,那么下标为⌊ 2/n ⌋ 的元素(下标从 0 开始)一定是众数。

class Solution:
    def majorityElement(self, nums: List[int]) -> int:
        nums.sort()
        return nums[len(nums)//2]

思路二:哈希表

class Solution:
    def majorityElement(self, nums):
        counts = collections.Counter(nums)
        return max(counts.keys(), key=counts.get)

时间复杂度:O(n)
空间复杂度:O(n)
思路三:摩尔投票法
遍历投票数组,将当前票数最多的候选人与其获得的(抵消后)票数分别存储在 major 与 count 中。
当我们遍历下一个选票时,判断当前count是否为零:
若 count == 0,代表当前major空缺,直接将当前候选人赋值给major,并令count++
若 count!=0,代表当前major的票数未被完全抵消,因此令 count–,即使用当前候选人的票数抵消major的票数
参考

major = 0
count = 0
for n in nums:
    if count == 0:
        major = n
    if n == major:
        count = count + 1
    else:
        count = count - 1

Leetcode-python 231. 2的幂

难度:简单 3 类型: 位运算
题目:给定一个整数,编写一个函数来判断它是否是 2 的幂次方。
解题思路
若n=2^x,则x为自然数,即n>0,(即n为 2的幂),则一定满足以下条件:
恒有n&(n-1)== 0,这是因为:
n二进制最高位为1,其余所有位为0;
n-1二进制最高位为0,其余所有位为1;
一定满足 n > 0。
因此,通过 n > 0 且 n & (n - 1) == 0 即可判定是否满足 n = 2^x。

class Solution:
    def isPowerOfTwo(self, n: int) -> bool:
        return n > 0 and n & (n - 1) == 0

Leetcode-python 268. 丢失的数字

难度:简单 3 类型: 位运算
题目:给定一个包含 [0, n] 中 n 个数的数组 nums ,找出 [0, n] 这个范围内没有出现在数组中的那个数。
进阶:你能否实现线性时间复杂度、仅使用额外常数空间的算法解决此问题?
解题思路
解题思路一:求和公式。

class Solution:
    def missingNumber(self, nums):
        n = len(nums)
        total = 0
        res = 0
        curSum = 0
        for i in range(n):
            total += nums[i]
        curSum = n * (n + 1) // 2
        res = curSum - total
        return res

解题思路二:异或0-n个数字。

class Solution:
    def missingNumber(self, nums):
        length = len(nums)
        res = length        #因为下面少异或了最后一个下标,所以初始值设置为最后一个下标
        for i in range(length):
            res ^= nums[i] ^ i
        return res

Leetcode-python 1342. 将数字变成0的操作次数

难度:简单 3 类型: 位运算
题目:给你一个非负整数 num ,请你返回将它变成 0 所需要的步数。 如果当前数字是偶数,你需要把它除以 2 ;否则,减去 1 。

class Solution:
    def numberOfSteps (self, num: int) -> int:
        count = 0
        while (num!=0):
            count+=1
            num=(num&-2) if ((num&1)==1) else (num>>1)
        return count

Leetcode-python 1290. 二进制链表转整数

难度:简单 3 类型: 位运算
题目:给你一个单链表的引用结点 head。链表中每个结点的值不是0就是1。已知此链表是一个整数数字的二进制表示形式。
请你返回该链表所表示数字的十进制值。
解题思路:位运算;从左往右。

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def getDecimalValue(self, head: ListNode) -> int:
        re = 0
        tmp = head
        while tmp:
            re = (re << 1) | tmp.val
            tmp = tmp.next
        return re
class Solution:
    def getDecimalValue(self, head: ListNode) -> int:
        res = 0
        cur = head 
        while cur:
            res = res*2 + cur.val * 2**0
            cur = cur.next
        return res
head=ListNode(1)
a=ListNode(0)
b=ListNode(1)
c=ListNode(1)
head.next=a
a.next=b
b.next=c
c.next=None
# 结果11

Leetcode-python 371. 两整数之和

难度:简单 3+ 类型: 位运算
题目:不使用运算符 + 和 - ​​​​​​​,计算两整数 ​​​​​​​a 、b ​​​​​​​之和。
解题思路:使用位运算。
位运算中的加法
在位运算操作中,异或的一个重要特性是无进位加法。

a = 5 = 0101
b = 4 = 0100
a ^ b 如下:
0 1 0 1
0 1 0 0
======
0 0 0 1

a ^ b 得到了一个无进位加法结果,如果要得到 a + b 的最终值,我们还要找到进位的数,把这二者相加。在位运算中,我们可以使用与操作获得进位。
与运算操作

a = 5 = 0101
b = 4 = 0100
a & b 如下:
0 1 0 1
0 1 0 0
======
0 1 0 0

由计算结果可见,0100 并不是我们想要的进位,1 + 1 所获得的进位应该要放置在它的更高位,即左侧位上,因此我们还要把 0100 左移一位,才是我们所要的进位结果。
那么问题就容易了,总结一下:
a + b 的问题拆分为 (a 和 b 的无进位结果) + (a 和 b 的进位结果)
无进位加法使用异或运算计算得出
进位结果使用与运算和移位运算计算得出
循环此过程,直到进位为 0

Leetcode-python 405. 数字转换为十六进制数

难度:简单 3 类型: 位运算
题目链接
解题思路
思路一:库函数

class Solution:
    def toHex(self, num: int) -> str:
       return hex(num&0xFFFFFFFF)[2:]

思路二:位运算

class Solution:
    def toHex(self, num: int) -> str:
        num &= 0xFFFFFFFF
        s = "0123456789abcdef"
        res = ""
        mask = 0b1111
        while num > 0:
            res += s[num & mask]
            num >>= 4
        return res[::-1] if res else "0"

media

hard

参考:https://www.jianshu.com/p/bcf65b047d1a

你可能感兴趣的:(leetcode)