字典内置操作时间复杂度:
copy O(n)
get item O(1)
set item O(1)
delete item O(1)
in O(1)
遍历 O(n)
列表内置函数时间复杂度:
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
题目链接
难度:简单 类型: 数组
题目:
解题思路:。
时间复杂度:
空间复杂度:
题目链接
难度:简单 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
题目链接
难度:简单 1 类型: 数组
解题思路:可以借用字典。
题目链接
难度:简单 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内存消耗一样。
题目链接
难度:简单 1 类型: 数组
题目链接
难度:简单 1 类型: 数组
题目链接
难度:简单 1 类型: 数组
题目:给定一个按非递减顺序排序的整数数组 A,返回每个数字的平方组成的新数组,要求也按非递减顺序排序。
class Solution(object):
def sortedSquares(self, A):
return sorted([x*x for x in A])
题目链接
难度:简单 1 类型: 数组
解题思路:最大储水量一个思路。
题目链接
难度:简单 1 类型: 数组
解题思路:最大储水量一个思路。
题目链接
难度:简单 1 类型: 数组
解题思路:借用字典。
题目链接
难度:简单 1 类型: 数组
解题思路:借用字典。
题目链接
难度:简单 1 类型: 数组
解题思路:使用二分查找法。
题目链接
难度:简单 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
题目链接
难度:简单 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 类型: 数组
题目:给定一个整型数组,在数组中找出由三个数组成的最大乘积,并输出这个乘积。
解题思路:将数组进行升序排序,如果数组中所有的元素都是非负数,那么答案即为最后三个元素的乘积。
如果数组中出现了负数,那么我们还需要考虑乘积中包含负数的情况,显然选择最小的两个负数和最大的一个正数是最优的,即为前两个元素与最后一个元素的乘积。
上述两个结果中的较大值就是答案。注意我们可以不用判断数组中到底有没有正数,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])
难度:简单 3 类型: 数组
难度:简单 3 类型: 数组
题目:给定一个按非递减顺序排序的整数数组 A,返回每个数字的平方后有几种不同的数。
class Solution(object):
def sortedSquares(self, A):
return sorted([x*x for x in A])
题目链接
难度:困难 类型: 数组
题目:给定一个直方图(也称柱状图),假设有人从上面源源不断地倒水,最后直方图能存多少水量?直方图的宽度为 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)) 简洁写法,生成器
难度:简单 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 类型: 位运算
题目:请实现一个函数,输入一个整数,输出该数二进制表示中 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
难度:简单 1 类型: 位运算
题目:给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
解题思路:典型的位运算。
class Solution:
def singleNumber(self, nums: List[int]) -> int:
res=0
for i in nums:
res^=i
return res
难度:简单 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))
难度:简单 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)
难度:简单 1 类型: 位运算
题目:两个整数之间的汉明距离指的是这两个数字对应二进制位不同的位置的数目。给出两个整数 x 和 y,计算它们之间的汉明距离。
class Solution:
def hammingDistance(self, x: int, y: int) -> int:
return bin(x^y).count('1')
难度:简单 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
难度:简单 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
难度:简单 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
难度:简单 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
难度:简单 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
难度:简单 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
难度:简单 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"
参考:https://www.jianshu.com/p/bcf65b047d1a