一136只出现一次的数字
这个符合规定的解法比较唯一:位运算
-
在程序中我们常常会用一个字段来记录多种简单的类型,例如,管理员管理帖子的时候,一个帖子有置顶,热议,精品等多个属性。这些属性又比较简单像置顶状态只有置顶和取消置顶两种状态;若是每一个字段都在数据库中加一个字段,若是状态比较多的话,就显的非常冗余;我们可以把这些属性通过位运算(一组特殊数值)存放在一个数据库的一个字段中。我们用这组数值来表示我们的一种状态(如1.置顶 2.取消置顶),之所以称之为一组特殊的数值,是因为这些存放状态的数值必须是2n。
-
什么是位运算?
位运算就是二进制数值按照位运算符&(与),|(或),~(取反),^(异或),>>(左移),<<(右移)对二进制数值进行运算,我们知道 程序中的所有数在计算机内存中都是以二进制的形式储存的。位运算说穿了,就是直接对整数在内存中的二进制位进行操作。
比如,and运算本来是一个逻辑运算符,但整数与整数之间也可以进行and运算。举个例子,6的二进制是110,11的二进制是1011,那么6 and 11的结果就是2,它是二进制对应位进行逻辑运算的结果(0表示False,1表示True,空位都当0处理)。
- ?二进制和十进制是怎么互相转化的
十进制和二进制的相互转化:把一个二进制数转化为十进制就是从右到左用二进制的每个数去乘以2的相应次方(次方要从0开始算起);
例如: 1101(2)=120+021+122+123=1+0+4+8=13;
class Solution:
def singleNumber(self, nums: List[int]) -> int:
for i in range(len(nums)-1):
nums[0]=nums[0]^nums[i+1]
return nums[0]
二141环形链表
如何判断闭环?
题解里给与了一种龟兔赛跑算法,具体可见力扣题解1
- 具体地,我们定义两个指针,一快一满。
- 慢指针每次只移动一步,而快指针每次移动两步。
- 初始时,慢指针在位置 head,而快指针在位置 head.next。
- 这样一来,如果在移动的过程中,快指针反过来追上慢指针,就说明该链表为环形链表。否则快指针将到达链表尾部,该链表不为环形链表。
基本格式:
while判断条件:
slow=slow.next
fast=fast.next.next
快慢指针的一个间隔和两个间隔不是固定的,但是取12是遍历次数最小或者说迭代速度最快的方式
class Solution:
def hasCycle(self, head: ListNode) -> bool:
if not head or not head.next:
return False
slow=head
fast=head.next
while fast.next:
if slow==fast:
return True
slow=slow.next
fast=fast.next
if fast.next:
fast=fast.next
else:
return False
return False
三142环形链表||
假设链表构造如图:
非闭环长度为1,闭环长度为b+c,而b为快慢指针在取值为12条件下慢指针覆盖长度:
建立在我们上一个问题对指针问题的研究,此时假设慢指针走过n圈,快指针走过n+1圈
那么就有如下等式:
这就是慢指针走过的路程+1圈=快指针走过的路程
然后我们要求解的是a对应的节点,即,我们会发现:
从相遇点到入环点的距离加上 n-1 圈的环长,恰好等于从链表头部到入环点的距离。
所以我们的模型即
按照问题二的141,建立快慢指针算法的相遇模型,求解相遇点:参考上半页
按照算法秒速的a=c+n~~,建立一个从head到入环点,和从相遇点到入环点的模型
class Solution:
def detectCycle(self, head: ListNode) -> ListNode:
if not head or not head.next:
return None
slow=head.next
fast=head.next.next
while slow!=fast:
try:
slow=slow.next
fast=fast.next.next
except:
return None
slow=head
while slow!=fast:
slow=slow.next
fast=fast.next
return slow