1.leetcode刷题记录--新手村

1480:一维数组动态和
给你一个数组 nums 。数组「动态和」的计算公式为:runningSum[i] = sum(nums[0]…nums[i]) 。
请返回 nums 的动态和。
解题思路:
动态和数组的每一个元素是当前元素加上之前元素的和。
具体步骤:
从题中知道输入的是nums数组,要返回nums的动态数组和nums。

  • runningSum[0]= mums[0] i=0,不用处理。
  • runningSum[i]=suningSum[i-1]+num[i] i>0, 表达为代码形式nums[i]+=nums[i-1],nums[i-1]为上一个元素的动态和。
class Solution {
public:
    vector<int> runningSum(vector<int>& nums) {
        int n = nums.size();
        for(int i =1; i<n;i++){//第一个元素的动态和就是mums[0]因此不用进入循环
            nums[i]+=nums[i-1];//nums[i-1]上一个动态和
        }
        return(nums);
    }
};

383. 赎金信
**给你两个字符串:ransomNote 和 magazine ,判断 ransomNote 能不能由 magazine 里面的字符构成。
如果可以,返回 true ;否则返回 false 。
magazine 中的每个字符只能在 ransomNote 中使用一次。

解题思路:

题目要求使用字符串magazine 中的字符来构建新的字符串 ransomNote,ransomNote 中的每个字符只能使用一次,只需要满足字符串magazine 中的每个英文字母 的统计次数都大于等于ransomNote 中相同字母的统计次数即可。

具体步骤

  • 情况1:magazine 的长度小于字符串 ransomNote 的长度,magazine 无法构成
    ransomNote,此时直接返回false。
  • 其他情况:首先统计magazine 中每个英文字母的次数 cnt[],再遍历ransomNote中每个英文字母的次数,如果发现ransomNote 中存在某个英文字母 的统计次数大于 magazine 中该字母统计次数直接返回 false。
class Solution {
public:
    bool canConstruct(string ransomNote, string magazine) {
     //情况1 如果ransomNote的组成字符串比magazine多那么肯定不能被magazine的字符构成
        if (ransomNote.size() > magazine.size()) {
            return false;
        }
       //其他情况
        vector<int> cnt(26);//定义最大容器空间为26(26个英文字母)的vector
        for (auto & c : magazine) {//统计magazine字符串中每个字母的数量
            cnt[c - 'a']++;
        }
        for (auto & c : ransomNote) {
            cnt[c - 'a']--;//ransomNote的字母是不是都在magazine中存在且少于
            if (cnt[c - 'a'] < 0) {
                return false;
            }
        }
        return true;
    }
};

用到的知识点:

  1. 哈希表
  2. C++ 中auto与auto&的区别

412. Fizz Buzz
给你一个整数 n ,找出从 1 到 n 各个整数的 Fizz Buzz 表示,并用字符串数组 answer(下标从 1 开始)返回结果,其中:

answer[i] == “FizzBuzz” 如果 i 同时是 3 和 5 的倍数。
answer[i] == “Fizz” 如果 i 是 3 的倍数。
answer[i] == “Buzz” 如果 i 是 5 的倍数。
answer[i] == i (以字符串形式)如果上述条件全不满足。
示例 :
输入:n = 15
输出:[“1”,“2”,“Fizz”,“4”,“Buzz”,“Fizz”,“7”,“8”,“Fizz”,“Buzz”,“11”,“Fizz”,“13”,“14”,“FizzBuzz”]

解题思路:

给定一个整数n,判断从1到n的每一个整数i是不是3,5的整数,如果不是就输出i的字符串形式,如果i是3的倍数就输出"Fizz" ,如果i是 5 的倍数就输出"Buzz", 如果 i 同时是 3 和 5 的倍数就输出"FizzBuzz" 。

具体步骤
1.判断是否是3的倍数
2.判断是不是5的倍数
3.如果都不是则输出i的字符串形式

class Solution{
    public:
    vector<string >fizzBuzz(int n){
        vector<string>answer;
        for(int i= 1;i<=n;i++){
            string curr;
           if(i%3==0) {
                curr+="Fizz";
            }
            if(i%5==0) {
                curr +="Buzz";
            }
            if(curr.size()==0) {
                curr+=to_string(i);
            }
            answer.emplace_back(curr);//在容器尾部添加一个元素,这个元素原地构造,不需要触发拷贝构造和转移构造。而且调用形式更加简洁,直接根据参数初始化临时对象的成员。
        }
        return answer;
    }
};//需要加分号

知识点:

  1. emplace_back()和push_back()

876. 链表的中间结点
给定一个头结点为 head 的非空单链表,返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点。

解题思路
F1(方法1):
链表的缺点在于不能通过下标访问对应的元素。因此我们可以考虑对链表进行遍历,同时将遍历到的元素依次放入数组 A 中。如果我们遍历到了 N 个元素,那么链表以及数组的长度也为 N,对应的中间节点即为 A[N/2]。

class Solution {
public:
    ListNode* middleNode(ListNode* head) {
        vector<ListNode*> A = {head};
        while (A.back()->next != NULL)
            A.push_back(A.back()->next);
        return A[A.size() / 2];
    }
};

相关知识:

  • c语言链表

F2:

解题思路:

我们可以对方法一进行空间优化,省去数组 A。我们可以对链表进行两次遍历。第一次遍历时,我们统计链表中的元素个数 N;第二次遍历时,我们遍历到第 N/2 个元素(链表的首节点为第 0 个元素)时,将该元素返回即可。

class Solution {
public:
    ListNode* middleNode(ListNode* head) {
        int n = 0;
        ListNode* cur = head;
        while (cur != nullptr) {
            ++n;
            cur = cur->next;
        }
        int k = 0;
        cur = head;
        while (k < n / 2) {
            ++k;
            cur = cur->next;
        }
        return cur;
    }
};

F3:

思路和算法

我们可以继续优化方法二,用两个指针 slow 与 fast 一起遍历链表。slow 一次走一步,fast 一次走两步。那么当 fast 到达链表的末尾时,slow 必然位于中间。

class Solution {
public:
    ListNode* middleNode(ListNode* head) {
        ListNode* slow = head;
        ListNode* fast = head;
        while (fast != NULL && fast->next != NULL) {
            slow = slow->next;
            fast = fast->next->next;
        }
        return slow;
    }
};

1342. 将数字变成 0 的操作次数
给你一个非负整数 num ,请你返回将它变成 0 所需要的步数。 如果当前数字是偶数,你需要把它除以 2 ;否则,减去 1 。

解题思路:
num 与 1进行位运算来判断 num 的奇偶性。

记录操作次数时:

  • 如果num 是奇数,我们需要加上一次减 1的操作。

    如果 num>1,我们需要加上一次除以 2的操作。

然后使num 的值变成⌊num/2⌋ 。重复以上操作直到num=0 时结束操作。

class Solution {
public:
    int numberOfSteps(int num) {
        int ret = 0;
        while (num) {
            ret += (num > 1 ? 1 : 0) + (num & 0x01);
            num >>= 1;
        }
        return ret;
    }
};

相关知识:

  • 位运算

1672. 最富有客户的资产总量

思路与算法:

分别计算每位客户在各家银行托管的资产数量之和,返回这些资产总量的最大值。

class Solution {
public:
    int maximumWealth(vector<vector<int>>& accounts) {
        int maxWealth = INT_MIN;
        for (auto &account : accounts) {
            maxWealth = max(maxWealth, accumulate(account.begin(), account.end(), 0));
        }
        return maxWealth;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

My.科研小菜鸡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值