Datawhale|LeetCodeTencent Task06(lc43,46,53)

043 Multiply Strings(M)

Description

在这里插入图片描述

输入为字符串表示的整数,输出二者的乘积,用字符串表示。不能直接把字符串转换为整数)。

Analysis & Solution

根据整数竖式乘法规则,可以发现以下规律:
整数A的第i位和整数B的第j位的乘积最终会出现在整数AB的第(i+j)位。
算法步骤为先将输入的两个字符串反转存入整数数组,根据以上规律,求出乘积每一位未处理进位前的值。然后处理进位,同时将结果转换为字符串,反转后输出。

Code

class Solution {
public:
    string multiply(string num1, string num2) {
        string ans;
        vector<int> a, b, c;
        c.resize(num1.size() + num2.size() - 1);
        for (int i = num1.size() - 1; i >= 0; i--) a.push_back(num1[i] - '0');
        for (int i = num2.size() - 1; i >= 0; i--) b.push_back(num2[i] - '0');
        for (int i = 0; i < a.size(); i++) {
            for (int j = 0; j < b.size(); j++) {
                c[i + j] += a[i] * b[j];
            }
        }
        int k = 0;
        for (int i = 0; i < c.size(); i++) {
            k += c[i];
            char c = k % 10 + '0';
            ans = c + ans;
            k /= 10;
        }
        while (k) {
            char c = k % 10 + '0';
            ans = c + ans;
            k /= 10;
        }
        while (ans.size() > 1 && ans[0] == '0') ans.erase(ans.begin());
        return ans;
    }
};

时间复杂度:涉及一次两层循环,时间复杂度为 O ( n 2 ) O(n^2) O(n2)

046 Permutations(M)

Description

在这里插入图片描述

题意为给出一个数组,求出数组所有元素的全排列并输出。

Analysis & Solution

本题用到的是回溯算法,先直接放上代码。

Code

vector<vector<int>> res;
vector<int> tempRes;
vector<int> flag;
void backtrack(vector<int>& nums)
{
    if(tempRes.size() == nums.size())
    {
        res.push_back(tempRes);
        return;
    }
    for(int i = 0; i < flag.size(); i++)
    {
        if(flag[i] == 1) continue;
        flag[i] = 1;
        tempRes.push_back(nums[i]);
        backtrack(nums);
        tempRes.pop_back();
        flag[i] = 0;
    }
    return;
}
vector<vector<int>> permute(vector<int>& nums)
{
    if(nums.size() == 0) return {{}};
    flag = vector<int>(nums.size(), 0);
    backtrack(nums);
    return res;
}

时间复杂度:仅对数组扫描一次,因此复杂度为 O ( n ) O(n) O(n)

053 Maximum Subarray(E)

Description

在这里插入图片描述

求最大子数组和,非常经典的算法问题,解法也比较多。

Analysis & Solution

(1)分治
用二分法,每次将数组按下标从中间等分,那么整个数组的最大子数组和就是左半数组的结果,右半数组的结果,横跨左右两部分结果的最大值。
左右两部分可以用递归解决,终止条件为仅有一个元素,返回元素本身。
横跨左右部分则用两个指针从中间分别向两边移动,直到扫过位置的和不再增大。
(2)动态规划
最优子结构 d p [ i ] dp[i] dp[i]表示以数组第i项A[i]结尾且包含A[i]的最大子数组和。
状态转移方程: d p [ i ] = m a x ( d p [ i − 1 ] + A [ i ] , A [ i ] ) dp[i]=max(dp[i-1]+A[i], A[i]) dp[i]=max(dp[i1]+A[i],A[i])
解释:两种选择,要么包含前i-1项子问题的结果,要么前面的全舍弃,只留A[i]。求这两种选择的结果的最大值。

Code

//dp
int maxSubArray(vector<int>& nums) 
{
    int N = nums.size();
    int dp[N];
    memset(dp, 0, sizeof(dp));
    dp[0] = nums[0];
    int maxSum = dp[0];
    for(int i = 1; i < N; i++)
    {
        dp[i] =  max(dp[i-1] + nums[i], nums[i]);
        if(dp[i] > maxSum) maxSum = dp[i];
    }
    return maxSum;
}
//divide and conquer
int MaxSubarray(vector<int>& A, int left, int right)
{
    if(left == right)
        return A[left];
    int mid = (left + right) / 2;
    int maxSumLeft = MaxSubarray(A, left, mid);
    int maxSumRight = MaxSubarray(A, mid + 1, right);
    int maxSumMidL = A[mid], maxSumMidR = A[mid + 1];
    int currentSum = 0;
    int i = mid, j = mid + 1;
    while(i >= left)
    {
        currentSum += A[i];
        maxSumMidL = max(maxSumMidL, currentSum);
        i--;
    }
    currentSum = 0;
    while(j <= right)
    {
        currentSum += A[j];
        maxSumMidR = max(maxSumMidR, currentSum);
        j++;
    }
    return max(max(maxSumLeft, maxSumRight), maxSumMidL + maxSumMidR);
}

时间复杂度:分治的时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn),动态规划的时间复杂度为 O ( n ) O(n) O(n)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值