题目链接
如果用哈希表做的话就十分的简单了,记录地址即可。不过O(1)内存的话就不考虑哈希表了。我们可以这么想这个问题,a + b + 重复路段 = b + a + 重复路段。这是相交的情况。不相交的情况是a + b = b + a。所以我们很容易用双指针来解决这个办法了,谁走到了尾部就换到下条路,换着走一次,路径总和是一样的。
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode* p1 = headA;
ListNode* p2 = headB;
while(p1 != p2){
p1 = p1 != nullptr ? p1->next : headB;
p2 = p2 != nullptr ? p2->next : headA;
}
return p1;
}
};
摩尔投票法
这个算法有点好玩题目链接
有排序,中位数就是众数的。有map记录的。都对,但是要么时间复杂度高了点要么就是要占用空间复杂度。
摩尔投票算法就是数字不一样我就把把个数减一,数字相同就把个数加一,个数划到为0的时候换下一个数字作为预备数,毕竟超过一半的数,那最后的数字一定是众数
class Solution {
public:
int majorityElement(vector<int>& nums) {
// 摩尔投票算法
int x = 0 , vote = 0;
for(const auto& val : nums){
if(vote == 0){
x = val;
}
vote += x == val ? 1 : -1;// 这样就能筛选出众数了,最后一个就是x了
}
return x;
}
};
把东西想成槽
题目链接
用栈去模拟,有一个新节点就消耗一个槽新增两个槽,空节点只消耗槽。当数据还没有处理完槽就已经空了的时候,说明序列化失败啦
class Solution {
public:
bool isValidSerialization(string preorder) {
int index = 0;
stack<int> st;
st.push(1); // 增加两个槽
while(index < preorder.size()){
if(st.empty())return false;// 槽用光了
if(preorder[index] == ','){
++index;
}
else if(preorder[index] == '#'){
st.top() -= 1;
if(st.top() == 0){
st.pop();
}
++index;
}
else{
while(index < preorder.size() && preorder[index] != ','){
++index;
}
st.top() -= 1;
if(st.top() == 0){
st.pop();
}
st.push(2);
}
}
return st.empty();
}
};
零和博弈
题目链接
可以用递归来去做,先手一定拿的牌是最好的,所以是max,而后手就是任人宰割只能选择min,因为先手已经帮我做好选择了。过程大概就是1、我先手拿左边到我后手拿牌最大值,2、我先手拿右边牌和后手拿牌的最大值。1和2比较一下选择最大的。
class Solution {
int first(const vector<int>& nums,int left,int right)
{
if(left == right){// 只有一张了
return nums[left];
}
return max(nums[left] + second(nums,left+1,right),nums[right] + second(nums,left,right-1));
}
int second(const vector<int>& nums,int left,int right){
if(left == right){
return 0;
}
return min(first(nums,left+1,right),first(nums,left,right-1));
}
public:
bool PredictTheWinner(vector<int>& nums) {
return first(nums,0,nums.size()-1) >= second(nums,0,nums.size()-1);
}
};