<1>160.https://leetcode.com/problems/intersection-of-two-linked-lists/
Answer:
如果两个List相交, 那么从相交点开始, 后面的Node是公共的,
想象着把两个List从后面开始对齐, 解题思路就比较清晰了:
需要把长链表前面的多余部分过滤掉, 然后逐个比较Node的地址.
先遍历两个List找到两者的长度, 然后长链表的指针先走|lenA-lenB|,
接着两个指针一起走, 边走边比较.
而第二种解法思路极其巧妙, 不容易想出来, 但实际上思路还是通过把两个链表的后端对齐, 对两个链表采用的一致的处理使得代码极其之少:
这种做法实际上等价于把链表A和B拼接起来, 这样大家的长度都是(lenA+lenB), 后端就对齐了.
ListA后面接ListB成为ListA->ListB (把这个虚拟链表称之为NewA),
ListB后面接ListA成为ListB->ListA (把这个虚拟链表称之为NewB),
两个指针分别从NewA和NewB的head开始, 边走边比较, 一定会相遇.
关于一定会相遇的结论, 需要一点证明:
相遇分两种情况:
原ListA与ListB无公共Node的情况下, 相遇于NewA与NewB的结尾, 是一个nullpointer;
原ListA与ListB有公共Node的情况下, 相遇于公共节点. 关于这一点, 需要回头看看NewA和NewB的尾部结构,
由于两个链表的拼接(分别成为NewA/NewB), NewA和NewB长度一致(lenA+lenB)且现在ListA和ListB已经是尾部对齐了, 两个指针同步向前移动, 一定会相遇与公共Node
进一步说明:
由于题目要求不能改变原ListA和ListB, 因此使用了当ListA的指针到达尾部nullpointer时转到headB的操作来避免两个链表的实际上的拼接;
while循环在循环(lenA+lenB+2)次之内一定会结束:
即如果无公共Node则在第(lenA+lenB+2)次循环时由于两个指针都为nullpointer而结束;
如果有公共Node则在更前面就因为相遇而结束了.
<2>169. https://leetcode.com/problems/majority-element/
Answer:
public class Solution {
public int majorityElement(int[] num) {
int major=num[0], count = 1;
for(int i=1; i<num.length;i++){
if(count==0){
count++;
major=num[i];
}else if(major==num[i]){
count++;
}else count--;
}
return major;
}
}
这个方法来自一篇论文:http://www.cs.utexas.edu/~moore/best-ideas/mjrty/
<3>189:https://leetcode.com/problems/rotate-array/
Answer:
有很多种解法,比较倾向这一种,如下所示:
class Solution {
public:
void rotate(vector<int>& nums, int k) {
k %=nums.size();
reverse(nums.begin(), nums.end());
reverse(nums.begin(), nums.begin()+k);
reverse(nums.begin()+k, nums.end());
}
};
<4>190.https://leetcode.com/problems/reverse-bits/
Answer:我说我怎么优化都不是100%呢?,答案长这个样子的O(0)空间!服气!
class Solution {
public:
uint32_t reverseBits(uint32_t n) {
n = (n >> 16) | (n << 16);
n = ((n & 0xff00ff00) >> 8) | ((n & 0x00ff00ff) << 8);
n = ((n & 0xf0f0f0f0) >> 4) | ((n & 0x0f0f0f0f) << 4);
n = ((n & 0xcccccccc) >> 2) | ((n & 0x33333333) << 2);
n = ((n & 0xaaaaaaaa) >> 1) | ((n & 0x55555555) << 1);
return n;
}
};
<5>191.https://leetcode.com/problems/number-of-1-bits/
Answer:
public class Solution {
public int hammingWeight(int n) {
int count = 0;
while(n != 0){
n = n & (n - 1);
count++;
}
return count;
}
}
<6>198:https://leetcode.com/problems/house-robber/
Answer:
方法有很多,可以参考讨论区第一条评论
class Solution {
public:
int rob(vector<int>& nums) {
if(nums.size()<=0) return 0;
int a1 = nums[0];
int a2 = 0;
for(int i=1;i<nums.size();i++) {
int tmp = a1;
a1 = max(a2+nums[i],a1);
a2 = tmp;
}
return a1;
}
};
<7>202:https://leetcode.com/problems/happy-number/
Answer:
这个题我答得非常不好,评论区中两种答案我都没用,导致击败率很低;
最好的答案是采用佛洛依德判环的算法。这里有疑问,就是为什么可以用这个方法?难道非快乐数一定会有环吗?
<8>268. Missing Number:https://leetcode.com/problems/missing-number/
Answer:
我认为比较好的答案,自己的方法是利用求和的方法来做的。
class Solution {
public:
int missingNumber(vector<int>& nums) {
int x1 = nums[0], x2 = 1;
for (int i = 1 ; i < nums.size() ; ++i) {
x1 ^= nums[i];
}
for (int i = 2 ; i <= nums.size() ; ++i) {
x2 ^= i;
}
return x1 ^ x2;
}
};
<8>475:https://leetcode.com/problems/heaters/
Answer:
引自leetcode:
class Solution {
public:
int findRadius(vector<int>& houses, vector<int>& heaters) {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int sol = 0;
sort(heaters.begin(),heaters.end());
for(int i = 0 ; i < houses.size() ; i++)
{
int actualIndex = lower_bound(heaters.begin(),heaters.end(),houses[i])-heaters.begin();
int rightDistance = actualIndex == heaters.size() ? INT_MAX : heaters[actualIndex]-houses[i];
int leftDistance = actualIndex <= 0 ? INT_MAX : houses[i]-heaters[actualIndex-1];
sol = max(sol,min(leftDistance,rightDistance));
}
return sol;
}
};