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 - 博客园
思路:遍历字符串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)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。