腾讯精选练习 50 题 Day11
题目:136. 只出现一次的数字
来源:力扣(LeetCode) https://leetcode-cn.com/problems/single-number/
【简单】给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
输入: [2,2,1]
输出: 1
解题思路
要实现该功能很简单,但要在o(n)时间复杂度和o(1)空间复杂度的情况下实现较难。
参考LeetCode官方题解的方法:
- 相同两个数做异或运算,结果为0
- 一个数和0 异或,结果还是这个数
- 故将所有数做异或运算,即可得到只出现一次的数
执行代码
class Solution {
public int singleNumber(int[] nums) {
int single = 0;
for (int num : nums) {
single ^= num;
}
return single;
}
}
复杂度
时间复杂度:O( n )
空间复杂度:O( 1 )
题目:141. 环形链表
简单的快慢指针的运用,故不做题解。
题目:142. 环形链表 II
来源:力扣(LeetCode)https://leetcode-cn.com/problems/linked-list-cycle-ii/
【中等】给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意,pos 仅仅是用于标识环的情况,并不会作为参数传递到函数中。
说明:不允许修改给定的链表。
进阶:
你是否可以使用 O(1) 空间解决此题?
输入:head = [3,2,0,-4], pos = 1
输出:返回索引为 1 的链表节点
解释:链表中有一个环,其尾部连接到第二个节点。
解题思路
使用哈希表可以很简单的做出来,但空间复杂度为o(n)。要实现o(1)的空间复杂度,需要用快慢指针法。
- 初始化:快指针fast指向头结点, 慢指针slow指向头结点
- 让fast一次走两步, slow一次走一步,第一次相遇在C处,停止
- 然后让fast指向头结点,slow原地不动,让后fast,slow每次走一步,当再次相遇,就是入口结点。
- 为什么相遇:当slow走到B点时,fast走到D点,B->D的距离是X。所以C->B的距离也是X,故相遇。
快慢指针:执行代码
public class Solution {
public ListNode detectCycle(ListNode head) {
if(head==null||head.next==null)
return null;
ListNode fast = head.next.next;
ListNode slow = head.next;
while(fast!=null&&fast.next!=null&&fast!=slow){
fast = fast.next.next;
slow = slow.next;
}
if(fast==null||fast.next==null) return null;
fast = head;
while(fast!=slow){
fast = fast.next;
slow = slow.next;
}
return fast;
}
}
复杂度
时间复杂度:O( n )
空间复杂度:O( 1 )