解法1:双指针
因为while每次循环需要进行条件判断,而range函数不需要,直接生成数字,因此时间复杂度更低。推荐使用range
class Solution:def reverseString(self, s: List[str]) -> None:"""Do not return anything, modify s in-place instead."""n = len(s)i, j = 0, n-1while i < j:#1.常见的交换数值# temp = s[i]# s[i] = s[j]# s[j] = temp#2.通过位运算的异或运算实现交换两个数的操作# s[i] = chr(ord(s[i]) ^ ord(s[j]))# s[j] = chr(ord(s[i]) ^ ord(s[j]))# s[i] = chr(ord(s[i]) ^ ord(s[j]))#3.s[i], s[j] = s[j], s[i]i += 1j -= 1
1.C++中库函数swap()(交换函数)在Python中的对应
2.swap函数实现的两种方式
swap可以有两种实现。
一种就是常见的交换数值:如1
一种就是通过位运算:如2
位运算是一种直接对二进制位进行操作的运算,通常用于底层编程、硬件控制和性能优化等场景。
位运算操作的对象是整数类型的数据(比如 int
),这些数据在计算机中以二进制形式存储。
位运算的主要特点是高效,因为它直接在二进制层面进行计算,通常比其他运算(如加减乘除)快。
按位异或(^)(常见位运算操作之一,还包括按位与(&),按位或(|),按位取反(~),左移(<<),右移(>>))
- 功能:两个数的每个位都进行逻辑异或操作(相同为 0,不同为 1)。
- 作用:可以用来翻转特定的二进制位。
- 示例:
位运算的应用场景
-
快速计算:
- 通过移位实现乘法和除法(如
x << 1
等价于x * 2
)。
- 通过移位实现乘法和除法(如
-
标志位操作:
- 用于设置、清除、切换特定位。例如,用按位与清除某个位,用按位或设置某个位。
-
判断奇偶性:
n & 1 == 0
表示偶数,n & 1 == 1
表示奇数。😍
-
位掩码:
- 通过掩码操作(与运算)保留特定的二进制位。
-
交换两个数:
- 通过异或运算实现:
-
a = a ^ b b = a ^ b a = a ^ b
3. 怎么理解通过异或运算实现交换两个数?
通过异或运算实现交换两个数的原理,利用了异或运算的性质:
- a⊕a=0 (一个数异或自身等于 0)
- a⊕0=a(一个数异或 0 等于自身)
- a⊕b⊕b=a(因为 b⊕b=0,所以 a⊕b⊕b=a)
实现步骤
设两个数分别为 a和 b,通过以下三步实现交换:
-
第一步:
a=a⊕b
此时,a 保存的是 a 和 b 的异或值。 -
第二步:
b=a⊕b
因为 a 现在是 a⊕b,所以 b 变成了:
b=(a⊕b)⊕b=a⊕(b⊕b)=a⊕0=a
此时 b 保存了原来的 a 值。 -
第三步:
a=a⊕b
因为 b 现在是原来的 a,所以 a 变成了:
a=(a⊕b)⊕b=a⊕(b⊕b)=a⊕0=b
此时 a 保存了原来的 b 值。
代码示例
以下是用 Python 实现的代码:
# 初始值 a = 5 # 二进制:0101 b = 3 # 二进制:0011# 交换过程 a = a ^ b # a = 0101 ^ 0011 = 0110 (a 变为 6) b = a ^ b # b = 0110 ^ 0011 = 0101 (b 变为 5) a = a ^ b # a = 0110 ^ 0101 = 0011 (a 变为 3)print("a =", a) # 输出:a = 3 print("b =", b) # 输出:b = 5
用异或实现交互两个数的操作为什么可以不用临时变量?
普通交换两个数的代码需要一个临时变量,通过异或实现交换的方式,不需要额外的变量,因为所有的信息都保存在 a 和 b 的二进制中。它通过数学逻辑直接完成交换。
注意事项
-
如果 a 和 b 指向同一个内存位置(如 a 和 b 是同一个变量),则这种方法不适用。因为会导致数据被清零:
a=a⊕a=0 -
在实际开发中,虽然异或交换节省了一个临时变量,但现代编译器优化已经非常强大,普通交换(用临时变量)也能生成高效的代码。因此异或交换主要用作教学示例或在极端优化场景下使用。
4. 如果是两个字符进行交换可以用这个方法吗?
异或运算可以用于交换两个字符,因为字符在底层是以整数形式(ASCII 或 Unicode 值)存储的,而异或操作本质上是对整数进行操作。只要将字符视为整数,就可以使用同样的方法实现交换。
Python 示例
以下是交换两个字符的代码:
# 初始值 a = 'A' # 字符 'A' 的 ASCII 值是 65 b = 'B' # 字符 'B' 的 ASCII 值是 66# 交换过程 a = chr(ord(a) ^ ord(b)) # 将字符转换为整数进行异或,再转回字符 b = chr(ord(a) ^ ord(b)) a = chr(ord(a) ^ ord(b))# 输出结果 print("a =", a) # 输出:a = B print("b =", b) # 输出:b = A
解释
ord()
:将字符转换为其对应的 ASCII 或 Unicode 值。例如,ord('A')
返回65
。chr()
:将整数值转换回字符。例如,chr(65)
返回'A'
。
通过 ord()
和 chr()
,可以在字符和整数之间自由转换,从而使用异或交换字符。
注意事项
- 适用范围:字符的交换适用于所有单个字符(如
'a'
、'A'
、'你'
),因为它们都可以被映射为整数。 - 不要用于字符串:如果需要交换的是多字符字符串,这种方法就不适用了,因为字符串不直接对应单个整数。
5.C++有^=这个符号,Python里面有^=这个符号吗?
是的,Python 中有 ^=
运算符,它是一种按位异或赋值运算符。
注意事项
^=
的作用范围:只适用于整数和可以转换为整数的数据(如字符)。- 与其他运算符类似:
^=
的用法与+=
、-=
、*=
等运算符一致,只是它对应的是异或操作。
解法2:使用栈
class Solution:def reverseString(self, s: List[str]) -> None:"""Do not return anything, modify s in-place instead."""stack = []for char in s:stack.append(char)for i in range(len(s)):s[i] = stack.pop()
1. Python中栈的表达:
stack = []
2. Python中加入元素到栈,和从栈中弹出元素的方法:
#加入栈 stack.append(char) #弹出栈 s[i] = stack.pop()
解法3:使用range
class Solution:def reverseString(self, s: List[str]) -> None:n = len(s)for i in range(n//2):s[i], s[n-i-1] = s[n-i-1], s[i]i += 1
1. python中“//”和“/”的区别是什么?
解法4:使用reversed
class Solution:def reverseString(self, s: List[str]) -> None:s[:] = reversed(s)
1. 介绍reversed函数和reverse函数
2.为什么表达成
s[:] = reversed(s)可以正确运行,但是
s = reversed(s)不行,以及
s[:]是什么意思?
解放5:使用切片
class Solution:def reverseString(self, s: List[str]) -> None:s[:] = s[::-1]
看不懂这个表达
解法6:使用列表推导
class Solution:def reverseString(self, s: List[str]) -> None:s[:] = [s[i] for i in range(len(s)-1, -1, -1)]
看不懂这个表达
解法7:使用reverse()
class Solution:def reverseString(self, s: List[str]) -> None:"""Do not return anything, modify s in-place instead."""# 原地反转,无返回值s.reverse()