Content
136. Single Number(E)
Description
Analysis & Solution
要求只用
O
(
n
)
O(n)
O(n)的时间复杂度,且不用额外空间。可以巧妙地运用位运算。
(1)相同数字位运算为1
(2)不同数字位运算为0
(3)非零整数与0位运算为整数本身
(4)位运算满足交换律
根据以上几条性质,数组中出现两次的数字进行位运算,结果为0。0与剩下的出现一次的数位运算就得该数本身。因此数组中所有元素位运算的结果就是本题目要求的输出。
Code
int singleNumber(vector<int>& nums)
{
int res = 0;
for(auto &p : nums)
res = res ^ p;
return res;
}
时间复杂度:遍历一次, O ( n ) O(n) O(n)。
141. Linked List Cycle(E)
Description
Analysis & Solution
判断链表是否有环,可使用快慢指针。
快指针从head开始,每次移动两步;慢指针从head开始每次移动一步。若链表无环,则快指针先到达末尾,指向NULL;若链表有环,则经过若干轮遍历,快慢指针必然会相遇。
Code
bool hasCycle(ListNode* head)
{
if(head == NULL || head->next == NULL) return false;
ListNode* fast = head->next, * slow = head;
while(fast != NULL && fast->next != NULL)
{
fast = fast->next->next;
slow = slow->next;
if(fast == slow) return true;
}
return false;
}
时间复杂度:常数次遍历就可以得到结果,时间复杂度为 O ( n ) O(n) O(n)。
142. Linked List Cycle II(M)
Description
Analysis & Solution
不仅要判断,链表是否有环,还要判断链表环出现的位置。设a的下一个位置是环节点,总节点数为a+b。
首先令快慢指针fast和slow进行移动,判断是否有环。由于fast移动距离是slow的两倍,且fast比slow多走了nb,因此slow走的距离是nb,fast为2nb。(n为正整数)
令指针p指向head,令p和slow同步移动,当p移动到a位置时,slow移动总距离为a+nb,这时p和slow恰好相遇。该位置就是题目所求位置。
Code
ListNode* detectCycle(ListNode* head)
{
bool hasCycle = false;
ListNode* fast = head, * slow = head;
while(fast != NULL && fast->next != NULL)
{
fast = fast->next->next;
slow = slow->next;
if(fast == slow)
{
hasCycle = true;
break;
}
}
if(hasCycle)
{
ListNode* p = head;
while(p != slow)
{
p = p->next;
slow = slow->next;
}
return p;
}
else return NULL;
}
时间复杂度:常数次遍历就可以得到结果,时间复杂度为 O ( n ) O(n) O(n)。