力扣刷题_数组_位运算


又开始刷题了,以前刷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<end:
    s[start], s[end] = s[end], s[start]
    start += 1
    end -= 1
'''
# 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。
在这里插入图片描述
上面是由数组 [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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,关于力扣刷C++常用操作,我可以给你一些常见的操作和技巧: 1. 使用 STL 容器和算法库:STL(Standard Template Library)是 C++ 标准库中的一个重要组成部分,包含了许多常用的容器和算法。在力扣刷中,使用 STL 可以大大提高代码的效率和可读性。例如,vector 可以用来存储动态数组,sort 可以用来排序等等。 2. 使用 auto 关键字:auto 关键字可以自动推导变量类型,可以减少代码量和提高可读性。例如,auto x = 1; 可以自动推导出 x 的类型为 int。 3. 使用 lambda 表达式:lambda 表达式是 C++11 中引入的一种匿名函数,可以方便地定义一些简单的函数对象。在力扣刷中,使用 lambda 表达式可以简化代码,例如在 sort 函数中自定义比较函数。 4. 使用位运算:位运算是一种高效的运算方式,在力扣刷中经常会用到。例如,左移运算符 << 可以用来计算 2 的幂次方,右移运算符 >> 可以用来除以 2 等等。 5. 使用递归:递归是一种常见的算法思想,在力扣刷中也经常会用到。例如,二叉树的遍历、链表的反转等等。 6. 使用 STL 中的 priority_queue:priority_queue 是 STL 中的一个容器,可以用来实现堆。在力扣刷中,使用 priority_queue 可以方便地实现一些需要维护最大值或最小值的算法。 7. 使用 STL 中的 unordered_map:unordered_map 是 STL 中的一个容器,可以用来实现哈希表。在力扣刷中,使用 unordered_map 可以方便地实现一些需要快速查找和插入的算法。 8. 使用 STL 中的 string:string 是 STL 中的一个容器,可以用来存储字符串。在力扣刷中,使用 string 可以方便地处理字符串相关的问。 9. 注意边界条件:在力扣刷中,边界条件往往是解决问的关键。需要仔细分析目,考虑各种边界情况,避免出现错误。 10. 注意时间复杂度:在力扣刷中,时间复杂度往往是评判代码优劣的重要指标。需要仔细分析算法的时间复杂度,并尽可能优化代码。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值