最近一些算法题的总结

在这里插入图片描述
题目链接
在这里插入图片描述
如果用哈希表做的话就十分的简单了,记录地址即可。不过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);
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值