剑指 Offer 第9天 第10天

 

目录

剑指 Offer 42. 连续子数组的最大和

 剑指 Offer 47. 礼物的最大价值

剑指 Offer 46. 把数字翻译成字符串

剑指 Offer 48. 最长不含重复字符的子字符串


剑指 Offer 42. 连续子数组的最大和

输入一个整型数组,数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。

要求时间复杂度为O(n)。

示例1:

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

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/lian-xu-zi-shu-zu-de-zui-da-he-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

【解法一】状态转移方程就是F(i) = max(nums[i], F[i-1]+nums[i]);

不过可以利用滚动数组思想进行优化

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        vector<int> dp(nums.size());
        dp[0] = nums[0];
        for(int i = 1; i < nums.size(); ++i)
        {
            dp[i] = max(nums[i], dp[i-1]+nums[i]);
        }
        int res = dp[0];
        for(auto e : dp)
        {
            if(res < e)
                res = e;
        }
        return res;
    }
};

【解法二】进行优化

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int pre = 0, res = nums[0];
        for(auto& e : nums)
        {
            pre = max(e, pre+e);
            res = max(pre, res);
        }
        return res;
    }
};

 剑指 Offer 47. 礼物的最大价值

在一个 m*n 的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于 0)。你可以从棋盘的左上角开始拿格子里的礼物,并每次向右或者向下移动一格、直到到达棋盘的右下角。给定一个棋盘及其上面的礼物的价值,请计算你最多能拿到多少价值的礼物?

示例 1:

输入:
[
  [1,3,1],
  [1,5,1],
  [4,2,1]
]
输出: 12
解释: 路径 1→3→5→2→1 可以拿到最多价值的礼物

【解法一】

class Solution {
public:
    int maxValue(vector<vector<int>>& grid) {
        for(int i = 1; i < grid.size(); i++)
            grid[i][0] += grid[i-1][0];
        for(int j = 1; j < grid[0].size(); j++)
            grid[0][j] += grid[0][j-1];
        for(int i = 1; i < grid.size(); i++)
        {
            for(int j = 1; j < grid[0].size(); j++)
            {
                grid[i][j] += max(grid[i-1][j], grid[i][j-1]);
            }
        }
        return grid[grid.size()-1][grid[0].size()-1];
    }
};

剑指 Offer 46. 把数字翻译成字符串

给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 “a” ,1 翻译成 “b”,……,11 翻译成 “l”,……,25 翻译成 “z”。一个数字可能有多个翻译。请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法。

示例 1:

输入: 12258
输出: 5
解释: 12258有5种不同的翻译,分别是"bccfi", "bwfi", "bczi", "mcfi"和"mzi"

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/ba-shu-zi-fan-yi-cheng-zi-fu-chuan-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

【解法一】动态规划,满足在0~25范围可以在dp[i-2]的基础上组成一个字符,如果不在范围,就只能单独成为一个字符,也就是dp[i-1]的值,初始化dp全为1,并且给最前方预留一个位置。

 

class Solution {
public:
    int translateNum(int num) {
        string nums(to_string(num));
        vector<int> dp(nums.size()+1, 1);
        for(int i = 1; i < nums.size(); i++)
        {
            if((nums[i-1]=='1'&&nums[i]>='0'&&nums[i]<='9') ||
                nums[i-1]=='2'&&nums[i]>='0'&&nums[i]<='5')
                dp[i+1] = dp[i]+dp[i-1];
            else 
                dp[i+1] = dp[i];
        }
        return dp[nums.size()];
    }
};

【解法二】滚动数组思想进行优化

class Solution {
public:
    int translateNum(int num) {
        string nums(to_string(num));
        int dp1 = 1, dp2 = 1, res = 1;
        for(int i = 1; i < nums.size(); i++)
        {
            if((nums[i-1]=='1'&&nums[i]>='0'&&nums[i]<='9') ||
                nums[i-1]=='2'&&nums[i]>='0'&&nums[i]<='5')
                res = dp1+dp2;
            else 
                res = dp2;
            dp1 = dp2;
            dp2 = res;
        }
        return res;
    }
};

剑指 Offer 48. 最长不含重复字符的子字符串

请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。

示例 1:

输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。

【解法一】转移方程为F(i) = max(i-j+1, F(i)) 在j-i为不重复字符串情况下  暴力!!!

具体做法:截取j到i的字符串,然后检测这个字符串看其是否重复。时间复杂度N^3

class Solution {
public:
    bool isrepeat(string s)
    {
        map<char,int> mp;
        for(auto e : s)
        {
            if(mp[e]==1)
                return false;
            else
                mp[e]++;
        }
        return true;
    }
    int lengthOfLongestSubstring(string s) {
        if(s.empty())return 0;
        vector<int> dp(s.size());
        int res = 1;
        for(int i = 1; i < s.size(); i++)
        {
            for(int j = 0; j < i; j++)
            {
                int len = i-j+1;
                string temp = s.substr(j, len);
                if(isrepeat(temp))
                {
                    dp[i] = max(len, dp[i]);
                    res = max(dp[i], res);
                }
            }
        }
        return res;
    }
};

【解法二】

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        vector<int> dp(128,-1);//存储每个字符最后出现的位置
        int i=0,j=0,res=0;
        for(;j<s.size();j++)
        {    
            if(dp[s[j]]<i)//前面的子串不含新加的字符
                res=max(res,j-i+1);
            else//当前字符在之前的子串中出现过            
                i=dp[s[j]]+1;//更新i,使得i到j没有重复字符
            dp[s[j]]=j;//更改当前字符出现的位置                               
        }
        return res;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值