Leetcode43 46 53

本文解析了三道经典算法题:字符串相乘、全排列及最大子序和,提供了详细的思路和实现代码,帮助读者理解算法背后的逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

43.字符串相乘

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

思路:应用数学中整数相乘的基本规律(类似于列竖式计算),即可得出结果。关键点在于对于得到两位数需要进位的考虑。
代码如下:

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[] result=new int[len];
        int k=0;
        for (int i = len1 - 1; i > -1; i--)
        {
            k = len1 - i;
            for (int j = len2 - 1; j > -1; j--)
            {
                int temp=(num1[i]-'0')*(num2[j]-'0');
                if (temp > 9)
                {
                    result[len - k] += temp % 10;
                    result[len - k - 1] += temp / 10;
                }
                else
                    result[len - k] += temp;
                if(result[len-k]>9)
                {
                    result[len-k-1]+=result[len-k]/10;
                    result[len-k]=result[len-k]%10;
                }
                k++;
            }
        }
        StringBuilder mul = new StringBuilder();
        int t = result[0] == 0 ? 1 : 0;
        for(;t<len;t++)
        {
            mul.Append(result[t]);
        }
        return mul.ToString();
    }
}

46.全排列

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

思路:本题采用回溯法,类似于图的深度优先搜索,数组里每一个元素都可以看作是一个分岔路口,先将路口元素标记为已访问状态(_used[i]==true)并加入到路径中,再接下去访问未被访问的元素,依次类推递归调用寻找路径的函数,每次找到最终路径后都需将上一个路口的访问状态重新设为未被访问(_used[i]==false),以寻找下一条可用路径。最终即可获得所有的路径,需注意list传递的是地址而不是拷贝,故而加入最终结果时应该加入它的拷贝结果(temp.AddRange(path)),而不是将其本身加入。
代码如下:

public class Solution
{
    private IList<IList<int>> _result;
    private bool[] _used;
    public IList<IList<int>> Permute(int[] nums)
    {
        int len = nums.Length;
        _result = new List<IList<int>>();
        _used = new bool[len];
        find(new List<int>(), nums, 0);
        return _result;
    }
    public void find(List<int> path, int[] nums,int count)
    {
        if (count == nums.Length)
        {
            List<int> temp = new List<int>();
            temp.AddRange(path);
            _result.Add(temp);
            return;
        }
        for (int i = 0; i < nums.Length; i++)
        {
            if (_used[i] == false)
            {
                path.Add(nums[i]);
                _used[i] = true;
                find(path, nums, count + 1);
                path.RemoveAt(path.Count - 1);
                _used[i] = false;
            }
        }
    }
}

53.最大子序和

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

思路:本题若使用暴力算法,思路十分简单。此外本题还可以采用动态规划的方法,使用一个max[]数组储存当前索引下,向前所能取到的最大子序和(两种情况,第一种是当前索引位置的数字加上此前的最大子序和,另一种是当前索引位置自己本身。),最终得到结果。
代码如下:

public class Solution
{
    public int MaxSubArray(int[] nums)
    {
        if (nums.Length == 0)
            return 0;
        if(nums.Length==1)
            return nums[0];
        int len=nums.Length;
        int[] max=new int[len];
        max[0]=nums[0];
        int result=max[0];
        for (int i = 1; i < len; i++)
        {
            if(nums[i]+max[i-1]>nums[i])
                max[i]=nums[i]+max[i-1];
            else
                max[i]=nums[i];
            if(result<max[i])
                result=max[i];
        }
        return result;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值