DW&LeetCode_day11(136、141、142)
写在前面:
- 这个月是跟并查集杠上了吗,这个月学不会并查集不让走!
开源内容
目录
DW&LeetCode_day11(136、141、142)
学习大纲
136. 只出现一次的数字
题解:
Python位运算符
按位运算符是把数字看作二进制来进行计算的。Python中的按位运算法则如下:
下表中变量 a 为 60,b 为 13,二进制格式如下:
a = 0011 1100 b = 0000 1101 ----------------- a&b = 0000 1100 a|b = 0011 1101 a^b = 0011 0001 ~a = 1100 0011
运算符 描述 实例 & 按位与运算符:参与运算的两个值,如果两个相应位都为1,则该位的结果为1,否则为0 (a & b) 输出结果 12 ,二进制解释: 0000 1100 | 按位或运算符:只要对应的二个二进位有一个为1时,结果位就为1。 (a | b) 输出结果 61 ,二进制解释: 0011 1101 ^ 按位异或运算符:当两对应的二进位相异时,结果为1 (a ^ b) 输出结果 49 ,二进制解释: 0011 0001 ~ 按位取反运算符:对数据的每个二进制位取反,即把1变为0,把0变为1 。~x 类似于 -x-1 (~a ) 输出结果 -61 ,二进制解释: 1100 0011,在一个有符号二进制数的补码形式。 << 左移动运算符:运算数的各二进位全部左移若干位,由 << 右边的数字指定了移动的位数,高位丢弃,低位补0。 a << 2 输出结果 240 ,二进制解释: 1111 0000 >> 右移动运算符:把">>"左边的运算数的各二进位全部右移若干位,>> 右边的数字指定了移动的位数 a >> 2 输出结果 15 ,二进制解释: 0000 1111 class Solution: def singleNumber(self, nums: List[int]) -> int: # 时间复杂度、空间复杂度全为O(n) for i in range(1, len(nums)):nums[0] ^= nums[i] # 位运算 return nums[0]
141. 环形链表
题解:
双指针法:
双指针主要用于遍历数组,两个指针指向不同的元素,从而协同完成任务。
题目描述:在有序数组中找出两个数,使它们的和为 target。
思路:使用双指针,一个指针指向值较小的元素,一个指针指向值较大的元素。指向较小元素的指针从头向尾遍历,指向较大元素的指针从尾向头遍历。输入: numbers={2, 7, 11, 15}, target=9 输出: [1,2]
- 如果两个指针指向元素的和 sum == target,那么得到要求的结果;
- 如果 sum > target,移动较大的元素,使 sum 变小一些;
- 如果 sum < target,移动较小的元素,使 sum 变大一些。
class Solution: def twoSum(self,nums,target): i,j = 0,len(nums)-1 while i<j: sum = nums[i]+nums[j] if sum < target: i += 1 elif sum > target: j -= 1 else: return [i+1,j+1] return None
class Solution: def hasCycle(self, head: ListNode) -> bool: p1, p2 = head, head #双指针 while 1: if not p2 or not p2.next: return False p1, p2 = p1.next, p2.next.next if p1 == p2: return True
142. 环形链表 II
题解:
- 若链表中存在环,则快慢指针在遍历链表时必定相遇;
- 若要求环的起点,则需要了解快慢指针的数学原理
def detectCycle(self, head: ListNode) -> ListNode: cur = head node_set = set() while cur: # 遍历链表,将遍历过的节点加入集合 if cur in node_set:return cur # 如果再次遍历到该节点,则该节点是环口返回 node_set.add(cur) cur = cur.next return cur