leetCode 刷题 (三)

344.反转字符串

编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。

不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。

示例 1:

输入:s = ["h","e","l","l","o"]
输出:["o","l","l","e","h"]
示例 2:

输入:s = ["H","a","n","n","a","h"]
输出:["h","a","n","n","a","H"]
 

提示:

1 <= s.length <= 105
s[i] 都是 ASCII 码表中的可打印字符

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/reverse-string
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

 方法:双指针,left从前,right从后,每次交换是s[left] 和s[right],left++,right--;只要left<right,不用考虑数组越界问题。

class Solution {
public:
    void reverseString(vector<char>& s) {
        //双指针法
        int n = s.size();
        int left =0, right = n-1;
        while(left<right){
            int temp = s[left];
            s[left] = s[right];
            s[right] = temp;
            left++;
            right--;
        }
    }
};

 

 557.反转字符串中的单词

给定一个字符串,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。

示例:

输入:"Let's take LeetCode contest"
输出:"s'teL ekat edoCteeL tsetnoc"
 

提示:

在字符串中,每个单词由单个空格分隔,并且字符串中不会有任何额外的空格。

 方法一:(复习一下string 的相关库函数)

【原创】C++自带string类的常用方法 - Engraver - 博客园

C++ string的常用函数用法总结 - 简书

思路:遍历字符串s,遇到空格代表遍历完一个单词,然后对该单词进行倒置,存入str中,然后继续,直至遍历完整个串s;

class Solution {
public:
    string reverseWords(string s) {
        vector<string> str;
        string ans;
        int k,str_begin;
        //string s(str, str_begin, str_len):将字符串str中从下标strbegin开始、长度为strlen的部分作为字符串初值
        for(int i=0;i<s.length();i++){
            if(s[i]!=' '){
                str_begin = i;
                k=0;
            }    
            while(i<s.length()&&s[i]!=' '){
                k++;
                i++;
            }
            string stemp(s,str_begin,k);
            //string 自带倒置函数
            reverse(stemp.begin(),stemp.end());
            str.push_back(stemp);
        }
        ans = str[0];
        for(int i=1;i<str.size();i++){
            ans = ans +" "+str[i];  
        }
        return ans;
    }
};

//整理版,上面的太乱,不整洁
class Solution {
public:
    string reverseWords(string s) {
        string ret;
        int length = s.length();
        int i = 0;
        while (i < length) {
            int start = i;
            while (i < length && s[i] != ' ') {
                i++;
            }
            for (int p = start; p < i; p++) {
                //逆序存入
                ret.push_back(s[start + i - 1 - p]);
            }
            while (i < length && s[i] == ' ') {
                i++;
                ret.push_back(' ');
            }
        }
        return ret;
    }
};

方法二:原地逆序,和上一个题联系起来。

遍历字符串s,记录一个单词开始的位置start和结束的位置end,然后利用双指针原地逆序;

class Solution {
public:
    string reverseWords(string s) {
        //原地逆序
        int length = s.length();
        for(int i=0;i<length;i++){
            int start = i;
            while(i<length&&s[i]!=' '){
                i++;
            }
            int end = i -1;
            while(start<end){
                swap(s[start],s[end]);
                start++;
                end--;
            }
        }
        return s;
    }
};

 

买卖股票的最佳时机 II

给定一个数组 prices ,其中 prices[i] 是一支给定股票第 i 天的价格。

设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。

注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

示例 1:

输入: prices = [7,1,5,3,6,4]
输出: 7
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
     随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6-3 = 3 。
示例 2:

输入: prices = [1,2,3,4,5]
输出: 4
解释: 在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
     注意你不能在第 1 天和第 2 天接连购买股票,之后再将它们卖出。因为这样属于同时参与了多笔交易,你必须在再次购买前出售掉之前的股票。
示例 3:

输入: prices = [7,6,4,3,1]
输出: 0
解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。

定义一个dp[][];
            规定:dp[i][0]表示第i天不持有股票的最大利润;dp[i][1]表示第i天持有股票的最大利润;
            初始值:dp[0][0] = 0;dp[i][1] = 0 - prices[1];
            传递关系:
            (1)第i天不持有股票的利润,有两种情况,1.第i-1天持有股票,则第i天的利润为dp[i-1][1]+prices[i];2.第i-1天不持有股票,则第i天利润为dp[i][0] = dp[i-1][0];
            (2)第i天持有股票的利润,也是两种。1.第i-1天持有股票,则dp[i][1] = dp[i-1][1];
            2.第i-1天不持有股票,则dp[i][1] = dp[i-1][0] - prices[i];

            由于最后一定是不持有股票比持有股票利润高,所以最大利润一定是dp[i][0];
            同时由于最后一天的利润情况只和前一天有关,座椅只需记录前一天的dp0和dp1;

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        //动态规划
        int n = prices.size();
        if(n==0)
            return 0;
        else{
            int dp0=0,dp1=0 - prices[0];
            for(int i=0;i<n;i++){
                int temp = dp0;
                dp0 = max(dp0,dp1+prices[i]);
                dp1 = max(dp1,temp-prices[i]);
            }
            return dp0;
        }
        
        
    }
};

作者:力扣 (LeetCode)
链接:https://leetcode-cn.com/leetbook/read/top-interview-questions-easy/x2zsx1/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值