Leetcode新手十题做题记录

1.1480 一维动态数组和

示例:

nums = [1,2,3,4]

输出:[1,3,6,10]

解释:动态和计算过程为 [1, 1+2, 1+2+3, 1+2+3+4] 。

我解:

class Solution {
public:
    vector<int> runningSum(vector<int>& nums) {
        int len = nums.size();
        vector<int> sum;
        for(int i=1;i<=len;i++)
        {
            int sumi=0;
            for(int j=0;j<i;j++)
            {
                sumi+=nums[j];
            }
            sum.push_back(sumi);
        }
        return sum;
    }
};

最笨的解法。时间复杂度:O(n^2) 空间复杂度:O(n)

优解:

class Solution {
public:
    vector<int> runningSum(vector<int>& nums) {
        int n = nums.size();
        for (int i = 1; i < n; i++) {
            nums[i] += nums[i - 1];
        }
        return nums;
    }
};

原地修改。

  • 时间复杂度:O(n),其中 nn 是给定数组长度。

  • 空间复杂度:O(1)。我们只需要常数的空间保存若干变量。

注意⚠️:

vector<int> vec;

for (int i = 0; i < vec.size() - 1; i++)

vec[i]

这里会有个隐藏问题,当vec的size为0时,因为size()函数的返回值是无符号整型,这时vec.size() - 1是一个正数,导致vec[i]的访问越界

size是指向vector中数组长度后的那一个位置,即size处没有元素

vector下标从0开始

2.1342 数字变0

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

我解:

class Solution {
public:
    int numberOfSteps(int num) {
        int times;
        for(times=0;num!=0;times++)
        {
            if(num%2==0&&num!=0){
            num/=2;
            //times++;
            }
        else if(num%2!=0&&num!=0){
            num-=1;
            //times++;
            }
        }  
        return times; 
    }   
};

优解:

遇到奇数减一除二、遇到偶数除二,本质上都是二进制的右移,只是奇数需要额外的一步。

出现奇数其实是在右移一定次数后,num & 1 == 1,也就是右移前该位为1。

出现偶数其实是在右移一定次数后,num & 1 == 0, 也就是右移前该位为0。

也就是说,每个二进制位的1都会带来两步的代价,每个二进制位的0都会带来一步的代价。

唯一特殊的是二进制最左的1最后减一为0不需要除二了,所以步数为1。

举个例子:

22 -> 11 -> 10 -> 5 -> 4 -> 2 -> 1 -> 0

10110 -> 1011 -> 1010 -> 101 -> 100 -> 10 -> 1 -> 0

class Solution:
    def numberOfSteps(self, num: int) -> int:
        return len(b:=bin(num)[2:]) + b.count('1') - 1

3.1672 最富有

给你一个 m x n 的整数网格 accounts ,其中 accounts[i][j] 是第 i​​​​​​​​​​​​ 位客户在第 j 家银行托管的资产数量。返回最富有客户所拥有的 资产总量 。

客户的 资产总量 就是他们在各家银行托管的资产数量之和。最富有客户就是 资产总量 最大的客户。

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;
    }
};

max accumulate都是内置函数

accumulate带有三个形参:头两个形参指定要累加的元素范围,第三个形参则是累加的初值。

accumulate函数将它的一个内部变量设置为指定的初始值,然后在此初值上累加输入范围内所有元素的值。accumulate算法返回累加的结果,其返回类型就是其第三个实参的类型。

可以使用accumulate把string型的vector容器中的元素连接起来:

string sum = accumulate(v.begin() , v.end() , string(" "));  

这个函数调用的效果是:从空字符串开始,把vec里的每个元素连接成一个字符串。

4. 412 FizzBuzz

5. 876 链表中间节点

6.383 赎金

给你两个字符串:ransomNote 和 magazine ,判断 ransomNote 能不能由 magazine 里面的字符构成。

如果可以,返回 true ;否则返回 false 。

magazine 中的每个字符只能在 ransomNote 中使用一次。

我解:
class Solution {
public:
    bool canConstruct(string ransomNote, string magazine) {
        int record[26]={0};
        for(int i=0;i<magazine.length();i++)
        {
            record[magazine[i]-'a']++;
        }
        for(int j = 0; j < ransomNote.length(); j++)
        {
            record[ransomNote[j]-'a']--;
            if(record[ransomNote[j]-'a']<0)
            return false;
        }
        return true;
    }
};

时间复杂度:O(m+n),其中m是字符串 ransomNote 的长度,n 是字符串 magazine的长度,我们只需要遍历两个字符一次即可。

空间复杂度:O(∣S∣),S是字符集,这道题中S为全部小写英语字母,因此 ∣S∣=26

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值