LeetCode腾讯50题-Day6-43/46/53

LeetCode50题(17天)-Day6

43 字符串相乘

  • 题号:43
  • 难度:中等
  • https://leetcode-cn.com/problems/multiply-strings/

给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。

示例 1:

输入: num1 = "2", num2 = "3"
输出: "6"

示例 2:

输入: num1 = "123", num2 = "456"
输出: "56088"

示例 3:

输入: num1 = "498828660196", num2 = "840477629533"
输出: "419254329864656431168468"

说明

  • num1 和 num2 的长度小于110。
  • num1 和 num2 只包含数字 0-9。
  • num1 和 num2 均不以零开头,除非是数字 0 本身。
  • 不能使用任何标准库的大数类型(比如 BigInteger)或直接将输入转换为整数来处理。

实现

public class Solution {
    public string Multiply(string num1, string num2) {
        if (num1 == "0" || num2 == "0")
            return "0";
        int len1 = num1.Length;
        int len2 = num2.Length;
        int len = len1 + len2;
        int[] temp = new int[len];

        for (int i = len2 - 1; i >= 0; i--)
        {
            int k = len2 - i;
            int b = num2[i] - '0';
            for (int j = len1 - 1; j >= 0; j--)
            {
                int a = num1[j] - '0';
                int c = a*b;

                temp[len - k] += c%10;
                if (temp[len - k] >= 10)
                {
                    temp[len - k] = temp[len - k]%10;
                    temp[len - k - 1]++;
                }

                temp[len - k - 1] += c/10;
                if (temp[len - k - 1] >= 10)
                {
                    temp[len - k - 1] = temp[len - k - 1]%10;
                    temp[len - k - 2]++;
                }
                k++;
            }
        }

        StringBuilder sb = new StringBuilder();
        int s = temp[0] == 0 ? 1 : 0;
        while (s < len)
        {
            sb.Append(temp[s]);
            s++;
        }
        return sb.ToString();        
    }
}

46 全排列

  • 题号:46
  • 难度:中等
  • https://leetcode-cn.com/problems/permutations/

给定一个没有重复数字的序列,返回其所有可能的全排列。

示例:

输入: [1,2,3]
输出:
[
  [1,2,3],
  [1,3,2],
  [2,1,3],
  [2,3,1],
  [3,1,2],
  [3,2,1]
]

实现

第一种:回溯法(back tracking) 是一种选优搜索法,又称为试探法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。

白话:回溯法可以理解为通过选择不同的岔路口寻找目的地,一个岔路口一个岔路口的去尝试找到目的地。如果走错了路,继续返回来找到岔路口的另一条路,直到找到目的地。

本练习的回溯过程如下所示:

回溯过程

public class Solution
{
    private IList<IList<int>> _result;
    private bool[] _used;

    public IList<IList<int>> Permute(int[] nums)
    {
        _result = new List<IList<int>>();
        if (nums == null || nums.Length == 0)
            return _result;
        _used = new bool[nums.Length];

        FindPath(nums, 0, new List<int>());
        return _result;
    }

    public void FindPath(int[] nums, int count, List<int> path)
    {
        if (count == nums.Length)
        {
            //递归终止条件
            List<int> item = new List<int>();
            item.AddRange(path);
            //加入拷贝
            _result.Add(item);
            return;
        }
        for (int i = 0; i < nums.Length; i++)
        {
            if (_used[i] == false)
            {
                path.Add(nums[i]);
                _used[i] = true;
                FindPath(nums, count + 1, path);
                path.RemoveAt(path.Count - 1);
                _used[i] = false;
            }
        }
    }
}

53 最大子序和

  • 题号:53
  • 难度:简单
  • https://leetcode-cn.com/problems/maximum-subarray/

给定一个整数数组 nums,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

示例 1:

输入: [-2,1,-3,4,-1,2,1,-5,4],
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6

示例 2:

输入: [-2,1],
输出: 1

进阶:

如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的分治法求解。


实现

第一种:利用暴力算法

  • 状态:通过
  • 202 / 202 个通过测试用例
  • 执行用时: 596 ms, 在所有 C# 提交中击败了 14.18% 的用户
  • 内存消耗: 24.5 MB, 在所有 C# 提交中击败了 5.88% 的用户
public class Solution {
    public int MaxSubArray(int[] nums) {
        int len = nums.Length;
        if (len == 0)
            return 0;
        if (len == 1)
            return nums[0];
        int max = int.MinValue;

        for (int i = 0; i < len; i++)
        {
            int sum = nums[i];
            if (sum > max)
            {
                max = sum;
            }
            for (int j = i + 1; j < len; j++)
            {
                sum += nums[j];
                if (sum > max)
                {
                    max = sum;
                }
            }
        }
        return max;        
    }
}

第二种:利用动态规划

动态规划的最优子结构如下:

max[i] = Max(max[i-1] + nums[i], nums[i])
  • 状态:通过
  • 202 / 202 个通过测试用例
  • 执行用时: 136 ms, 在所有 C# 提交中击败了 91.85% 的用户
  • 内存消耗: 24.4 MB, 在所有 C# 提交中击败了 5.88% 的用户
public class Solution {
    public int MaxSubArray(int[] nums) {
        int len = nums.Length;
        if (len == 0)
            return 0;
        if (len == 1)
            return nums[0];
        int[] max = new int[len];
        max[0] = nums[0];
        int result = max[0];
        for (int i = 1; i < len; i++)
        {
            if (max[i - 1] + nums[i] > nums[i])
            {
                max[i] = max[i - 1] + nums[i];
            }
            else
            {
                max[i] = nums[i];
            }
            
            if (max[i] > result)
            {
                result = max[i];
            }
        }
        return result;      
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值