**本文链接:**https://blog.csdn.net/qq_34811382/article/details/113002862
136 只出现一次的数字
思路:
利用位运算,看到这个题想到了我之前做的一道题,于是想着位运算可能简单一点。
利用 异或运算,^ (二进制,各位不同取1,相同取0.) 0=a ^ a ,a=0 ^ a, a=a^ b ^ b
代码:
class Solution
{
public:
int singleNumber(vector<int> &nums)
{
int result = 0;
for (int i = 0; i < nums.size();i++)
result ^= nums[i];
return result;
}
};
141 环形链表
思路:
定义两个指针,v1和v2,v2的速度是v1的n倍。我取得是2倍,相对速度,如果为环形链表,两者总会相遇。
代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution
{
public:
bool hasCycle(ListNode *head)
{
if(head==nullptr)
return false;
ListNode *v1 = head;
ListNode *v2 = head;
while (v1!=nullptr&&v2!=nullptr&&v2->next!=nullptr)
{
v1 = v1->next;
v2 = v2->next->next;
if (v1 == v2)
return true;
}
return false;
}
};
思路:
取巧法 题目中给了说节点的范围是0-10000,我们不妨让它跑10000次
代码:
class Solution
{
public:
bool hasCycle(ListNode *head)
{
ListNode *p1 = head;
for (int i = 0; i <= 10001; i++)
{
if (p1 == nullptr)
return false;
p1 = p1->next;
}
return true;
}
};
142. 环形链表 II
思路:
类似141题,取巧法,双重循环+暴力解决
代码:
class Solution
{
public:
ListNode *detectCycle(ListNode *head)
{
if (head == nullptr)
return nullptr;
ListNode *p1 = head;
ListNode *p2 = p1->next;
for (int i = 0; i < 10001; i++)
{
for (int j = 0; j < 10001; j++)
{
if (p1 == p2)
return p1;
if (p2 == nullptr)
return nullptr;
p2 = p2->next;
}
p1 = p1->next;
}
return nullptr;
}
};
思路:
看的题解,有大佬想出来的通过地址距离来判断,这真是一个好办法。单链表中节点与第一个节点的距离是不断增大的,如果出现减小的情况,就是出现环了。
代码:
class Solution
{
public:
ListNode *detectCycle(ListNode *head)
{
if (head == nullptr)
return nullptr;
long long adlen = 0;
long long admax = 0;
ListNode *Tou = head;
head = head->next;
while (head != nullptr)
{
adlen = head - Tou;
if (adlen > admax)
admax = adlen;
else
return head;
head = head->next;
}
return nullptr;
}
};