文章目录
717-1比特与2比特字符
有两种特殊字符。第一种字符可以用一比特0来表示。第二种字符可以用两比特(10 或 11)来表示。
现给一个由若干比特组成的字符串。问最后一个字符是否必定为一个一比特字符。给定的字符串总是由0结束。
这个题只要看最后一步是跳了一步,还是两步,如果只跳一步就会跳到最后一个位置,但是如果跳两步就会跳到外面去
这题让我知道了要观察处理数据的方式,
/*有两种特殊字符。第一种字符可以用一比特0来表示。第二种字符可以用两比特(10 或 11)来表示。
现给一个由若干比特组成的字符串。问最后一个字符是否必定为一个一比特字符。给定的字符串总是由0结束。*/
#include<iostream>
#include<vector>
using namespace std;
class Solution {
public:
bool isOneBitCharacter(vector<int>& bits)
{
int i = 0;
for (; i < bits.size()-1;)
{
if (bits[i] == 0)
i += 1; //如果是0,则跳一步,因为如果是0,则只能是1比特字符
else
{
i += 2; //如果是1,则跳两步,因为如果是1,则只能是2比特字符
}
}
if (i == bits.size() - 1) //说明最后一步跳的是1,则是1比特字符
return true;
else
{
return false;
}
}
};
int main()
{
vector<int>Check = { 0,1,0 };
Solution X;
if (X.isOneBitCharacter(Check))
{
cout << "this is true" << endl;
}
else {
cout << "false" << endl;
}
return 0;
}
14.最长公共前缀
这题让我知道了字符串之间是靠第一个不同字母的asii码值大小来进行排序的。
让我灵活用到了子串的获取函数,获取vector容器中的第一个和最后一个元素的函数。
vector容器里面也能够存放字符串,这个得清楚。
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;
/* 写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 ""*/
class Solution {
public:
string longestCommonPrefix(vector<string>& strs)
{
if (strs.empty())
return string();
sort(strs.begin(), strs.end()); //字符串排序的原则就是看第一个不相同字符的asii码值的大小,从而第一个字符串和第二个字符串的最长公共前缀就是整个的最长公共前缀
string first = strs.front();
string last = strs.back();
int i;
for (i = 0; i < first.size(); i++)
{
if (first.at(i) != last.at(i))
break;
}
return first.substr(0, i);
}
};
int main()
{
vector<string>str1 = { "flow","flower","flast" };
Solution X;
cout << X.longestCommonPrefix(str1) << endl;
return 0;
}
67.二进制求和
class Solution {
public:
string addBinary(string a, string b) {
int al = a.size();
int bl = b.size();
while (al < bl) //让两个字符串等长,若不等长,在短的字符串前补零,否则之后的操作会超出索引
{
a = '0' + a;
++al;
}
while (al > bl)
{
b = '0' + b;
++bl;
}
for (int j = a.size() - 1; j > 0; --j) //从后到前遍历所有的位数,同位相加
{
a[j] = a[j] - '0' + b[j];
if (a[j] >= '2') //若大于等于字符‘2’,需要进一
{
a[j] = (a[j] - '0') % 2 + '0';
a[j - 1] = a[j - 1] + 1;
}
}
a[0] = a[0] - '0' + b[0]; //将ab的第0位相加
if (a[0] >= '2') //若大于等于2,需要进一
{
a[0] = (a[0] - '0') % 2 + '0';
a = '1' + a;
}
return a;
}
};
20.有效的括号
/*给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
*/
#include<iostream>
using namespace std;
#include<string>
#include<stack>
class Solution {
public:
bool isValid(string s) {
cin >> s;
cout << s;
stack<char>Stack;
int i;
if (!s.size() % 2) //if the length of the string is cardinal number,the answer is wrong.
return 0;
for (i = 0; i < s.size() - 1; i++)
{
if (s[i] == '(')
Stack.push(s[i]);
if (s[i] == '[')
Stack.push(s[i]);
if (s[i] == '{')
Stack.push(s[i]);
if (s[i] == ')')
{
if (Stack.top() == '(')
Stack.pop();
else
{
return 0;
}
}
if (s[i] == ']')
{
if (Stack.top() == '[')
Stack.pop();
else
{
return 0;
}
}
if (s[i] == '}')
{
if (Stack.top() == '{')
Stack.pop();
else
{
return 0;
}
}
}
if(Stack.empty())
return true;
}
};
int main()
{
Solution S1;
string s;
if (S1.isValid(s))
{
cout << "success" << endl;
}
return 0;
}
258.各位相加
给定一个非负整数 num,反复将各个位上的数字相加,直到结果为一位数。
示例 :
输入: 38
输出 : 2
解释 : 各位相加的过程为:3 + 8 = 11, 1 + 1 = 2。 由于 2 是一位数,所以返回 2。
这题,需要知道如何获取各个位上的值,通过不断除10再取余来获得,并要知道这里使用递归,自己调用自己。
/*给定一个非负整数 num,反复将各个位上的数字相加,直到结果为一位数。
示例 :
输入: 38
输出 : 2
解释 : 各位相加的过程为:3 + 8 = 11, 1 + 1 = 2。 由于 2 是一位数,所以返回 2。*/
#include<iostream>
using namespace std;
class Solution {
public:
int addDigits(int num)
{
int temp = 0;
while (num)
{
temp += num % 10;
num /= 10;
}
if (temp >= 10)
{
return addDigits(temp);
}
else
{
return temp;
}
}
};
int main()
{
Solution S;
cout << S.addDigits(38) << endl;
return 0;
}
415.字符串相加
给定两个字符串形式的非负整数 num1 和num2 ,计算它们的和。
这题我想到的是就是列竖式,逐位相加,所以算之前,先补零,然后字符串的第一位留着最后算,以防越界。
还可以不用补零,直接算,算一位,就将这一位的答案放到一个字符串中去,最后算完之后,将得到的这个字符串反转过来就是我们要的答案。
提示:
num1 和num2 的长度都小于 5100
num1 和num2 都只包含数字 0 - 9
num1 和num2 都不包含任何前导零
你不能使用任何內建 BigInteger 库, 也不能直接将输入的字符串转换为整数形式
/*给定两个字符串形式的非负整数 num1 和num2 ,计算它们的和。
提示:
num1 和num2 的长度都小于 5100
num1 和num2 都只包含数字 0 - 9
num1 和num2 都不包含任何前导零
你不能使用任何內建 BigInteger 库, 也不能直接将输入的字符串转换为整数形式*/
#include<iostream>
using namespace std;
#include<string>
class Solution {
public:
string addStrings(string num1, string num2) {
while (num1.size()<num2.size()) //补位,使两个字符串位数相同
{
num1 = '0' + num1;
}
while (num2.size() < num1.size())
{
num2 = '0' + num2;
}
int i;
for (i=num1.size()-1;i>0;i--) //从最后一位开始计算,满10进1,第一位不计算最后再做处理,以防越位。
{
num1[i] = num1[i] + (num2[i]-'0');
if (num1[i]-'0' >= 10)
{
num1[i] = num1[i] - 10;
num1[i - 1] += 1;
}
}
if ((num1[0]-'0' )+( num2[0]-'0') >= 10)
{
num1[0] = num1[0] + (num2[0] - '0');
num1[0] -= 10;
num1 = '1' + num1;
}
else
{
num1[0] = num1[0] + (num2[0]-'0');
}
return num1;
}
};
int main()
{
Solution s1;
cout << s1.addStrings("1", "9") << endl;
}
989.数组形式的整数加法
对于非负整数 X 而言,X 的数组形式是每位数字按从左到右的顺序形成的数组。例如,如果 X = 1231,那么其数组形式为 [1, 2, 3, 1]。
给定非负整数 X 的数组形式 A,返回整数 X + K 的数组形式。
示例 1:
输入:A = [1, 2, 0, 0], K = 34
输出:[1, 2, 3, 4]
解释:1200 + 34 = 1234
示例 2:
输入:A = [2, 7, 4], K = 181
输出:[4, 5, 5]
解释:274 + 181 = 455
示例 3:
输入:A = [2, 1, 5], K = 806
输出:[1, 0, 2, 1]
解释:215 + 806 = 1021
示例 4:
输入:A = [9, 9, 9, 9, 9, 9, 9, 9, 9, 9], K = 1
输出:[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
解释:9999999999 + 1 = 10000000000
提示:
1 <= A.length <= 10000
0 <= A[i] <= 9
0 <= K <= 10000
如果 A.length > 1,那么 A[0] != 0*/
我先是将数组里面的数据弄成一个数temp,然后再让这个数加上 k;之后用不断取余的方法将数放入一个新的容器中,再将容器中的数reverse,就能得到我们要的结果,但是如果,数组长度稍微长一点,就很容易超出int类型的范围,因此我们直接一位一位的进行加,并一位一位地放入新的容器中。还有,遍历容器中的数据时,V.size()-1,后面这个-1别忘了,不然很容易越界。
/*对于非负整数 X 而言,X 的数组形式是每位数字按从左到右的顺序形成的数组。例如,如果 X = 1231,那么其数组形式为 [1, 2, 3, 1]。
给定非负整数 X 的数组形式 A,返回整数 X + K 的数组形式。
示例 1:
输入:A = [1, 2, 0, 0], K = 34
输出:[1, 2, 3, 4]
解释:1200 + 34 = 1234
示例 2:
输入:A = [2, 7, 4], K = 181
输出:[4, 5, 5]
解释:274 + 181 = 455
示例 3:
输入:A = [2, 1, 5], K = 806
输出:[1, 0, 2, 1]
解释:215 + 806 = 1021
示例 4:
输入:A = [9, 9, 9, 9, 9, 9, 9, 9, 9, 9], K = 1
输出:[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
解释:9999999999 + 1 = 10000000000
提示:
1 <= A.length <= 10000
0 <= A[i] <= 9
0 <= K <= 10000
如果 A.length > 1,那么 A[0] != 0*/
#include<iostream>
using namespace std;
#include<vector>
#include<math.h>
#include<algorithm>
class Solution {
public:
vector<int> addToArrayForm(vector<int>& num, int k) {
vector<int> res;
int n = num.size();
for (int i = n - 1; i >= 0; --i) {
int sum = num[i] + k % 10;
k /= 10;
if (sum >= 10) {
k++;
sum -= 10;
}
res.push_back(sum);
}
for (; k > 0; k /= 10) {
res.push_back(k % 10);
}
reverse(res.begin(), res.end());
return res;
}
};
void PrintVector(vector<int>V)
{
for (vector<int>::iterator it = V.begin(); it != V.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
int main()
{
vector<int>num;
int i, temp = 0;
for (i = 0; i < 10; i++)
{
cin >> temp;
num.push_back(temp);
}
PrintVector(num);
Solution s;
vector<int>newA=s.addToArrayForm(num, 1);
PrintVector(newA);
return 0;
}
441.排列硬币
你总共有 n 枚硬币,你需要将它们摆成一个阶梯形状,第 k 行就必须正好有 k 枚硬币。
给定一个数字 n,找出可形成完整阶梯行的总行数。
n 是一个非负整数,并且在32位有符号整型的范围内
首先想到的就是暴力,能放满一行就+1,直到放不满。
/*你总共有 n 枚硬币,你需要将它们摆成一个阶梯形状,第 k 行就必须正好有 k 枚硬币。
给定一个数字 n,找出可形成完整阶梯行的总行数。
n 是一个非负整数,并且在32位有符号整型的范围内*/
#include<iostream>
using namespace std;
class Solution {
public:
int arrangeCoins(int n) {
int column = 1;
int index = 0; //放满的行数
while (n >= column)//n理解为剩下的coin,column是没行要放的硬币数,如果大于就能放满这行。
{
n -= column;
column++;
index++;
}
return index;
}
};
int main()
{
Solution s;
cout << s.arrangeCoins(5) << endl;
return 0;
}
561.数组拆分
给定长度为 2n 的整数数组 nums ,你的任务是将这些数分成 n 对, 例如(a1, b1), (a2, b2), …, (an, bn) ,使得从 1 到 n 的 min(ai, bi) 总和最大。
返回该 最大总和 。
输入:nums = [6,2,6,5,1,2]
输出:9
解释:最优的分法为 (2, 1), (2, 5), (6, 6). min(2, 1) + min(2, 5) + min(6, 6) = 1 + 2 + 6 = 9
看例子就可以发现,让数组进行排序之后所分成的数组就能使总和最大
/*给定长度为 2n 的整数数组 nums ,你的任务是将这些数分成 n 对, 例如(a1, b1), (a2, b2), ..., (an, bn) ,使得从 1 到 n 的 min(ai, bi) 总和最大。
返回该 最大总和 。
输入:nums = [6,2,6,5,1,2]
输出:9
解释:最优的分法为 (2, 1), (2, 5), (6, 6). min(2, 1) + min(2, 5) + min(6, 6) = 1 + 2 + 6 = 9
*/
#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
class Solution {
public:
int arrayPairSum(vector<int>& nums) {
int Maxsun = 0;
sort(nums.begin(), nums.end()); //排序
int i = 0;
for (i = 0; i < nums.size(); i += 2) //将容器里位置为奇数的数相加的和就是最大值,因为拆分后数组的最小值位置都在奇数位置上
{
Maxsun += nums[i];
}
return Maxsun;
}
};
int main()
{
return 0;
}
445.分发饼干
假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。
对每个孩子 i,都有一个胃口值 g[i],这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j,都有一个尺寸 s[j] 。如果 s[j] >= g[i],
我们可以将这个饼干 j 分配给孩子 i ,这个孩子会得到满足。你的目标是尽可能满足越多数量的孩子,并输出这个最大数值。
首先想到的就是贪心算法,用最小的饼干满足小孩子,将孩子遍历完,就可以知道满足了多少个小孩子,开始之前得先排序。
可以直接用c++自带的算法函数。得注意的是break之后是直接跳出循环,不会再在循环体内进行for的第三步操作
/*假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。
对每个孩子 i,都有一个胃口值 g[i],这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j,都有一个尺寸 s[j] 。如果 s[j] >= g[i],
我们可以将这个饼干 j 分配给孩子 i ,这个孩子会得到满足。你的目标是尽可能满足越多数量的孩子,并输出这个最大数值。
示例 1 :
输入: g = [1, 2, 3], s = [1, 1]
输出 : 1
解释 :
你有三个孩子和两块小饼干,3个孩子的胃口值分别是:1, 2, 3。
虽然你有两块小饼干,由于他们的尺寸都是1,你只能让胃口值是1的孩子满足。
所以你应该输出1。
示例 2 :
输入: g = [1, 2], s = [1, 2, 3]
输出 : 2
解释 :
你有两个孩子和三块小饼干,2个孩子的胃口值分别是1, 2。
你拥有的饼干数量和尺寸都足以让所有孩子满足。
所以你应该输出2.
*/
#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
// g 1,2,3 s 3
class Solution {
public:
int findContentChildren(vector<int>& g, vector<int>& s) {
sort(g.begin(), g.end()); //排序
sort(s.begin(), s.end());
int s_length = s.size(), g_lenth = g.size();
int index = 0, i, j = 0; //index记录满足孩子的人数
for (i = 0; i < g_lenth; i++) //遍历孩子,找到满足他的最小饼干。
{
for (j; j < s_length;j++)
{
if (s[j] >= g[i])
{
index++;
j++;
break; //break之后不会再在循环体内使j+1,所以得自己加一。
}
}
}
return index;
}
};
int main()
{
vector<int>g;
g.push_back(1);
g.push_back(2);
g.push_back(3);
vector<int>s;
s.push_back(3);
Solution X;
cout << X.findContentChildren(g, s) << endl;
return 0;
}
1491.去掉最低薪资和最高薪资之后的平均数
给你一个整数数组 salary ,数组里每个数都是 唯一 的,其中 salary[i] 是第 i 个员工的工资
请你返回去掉最低工资和最高工资以后,剩下员工工资的平均值。
这题特别简单,遍历一次就行了,遍历的过程找到最小值和最大值并加和。
//给你一个整数数组 salary ,数组里每个数都是 唯一 的,其中 salary[i] 是第 i 个员工的工资。
//
//请你返回去掉最低工资和最高工资以后,剩下员工工资的平均值。
#include<iostream>
using namespace std;
#include<vector>
class Solution {
public:
double average(vector<int>& salary) {
int max = salary[0], min = salary[0];
int sum = 0;
for (vector<int>::iterator p = salary.begin(); p != salary.end(); p++)
{
if (*p > max)
{
max = *p;
}
if (*p < min)
{
min = *p;
}
sum += *p;
}
return (sum - min - max) * (1.0) / (salary.size() - 2);
}
};
int main()
{
return 0;
}
844.比较含退格的字符串
给定 S 和 T 两个字符串,当它们分别被输入到空白的文本编辑器后,判断二者是否相等,并返回结果。 # 代表退格字符。
注意:如果对空文本输入退格字符,文本继续为空。
示例 1:
输入:S = “ab#c”, T = “ad#c”
输出:true
解释:S 和 T 都会变成 “ac”。
另外建立两个字符串存放变化后的数据,遍历原先字符串,如果不为‘#’,就直接拼接到新的字符串,如果为‘#’,先判断新的字符串是否为空,为空则直接跳过删除,不为空,则用string里自带的eraze函数,注意删除的是新的字符串的位置。
/*给定 S 和 T 两个字符串,当它们分别被输入到空白的文本编辑器后,判断二者是否相等,并返回结果。 # 代表退格字符。
注意:如果对空文本输入退格字符,文本继续为空。
示例 1:
输入:S = "ab#c", T = "ad#c"
输出:true
解释:S 和 T 都会变成 “ac”。*/
#include<iostream>
using namespace std;
#include<string>
class Solution {
public:
bool backspaceCompare(string s, string t) {
string s_temp, t_temp;
int i;
for (i = 0; i < s.size(); i++)
{
if (s[i] != '#')
{
s_temp += s[i];
}
else
{
if (s_temp.size() == 0)
{
}
else
{
s_temp.erase(s_temp.size()-1, 1);
}
}
}
for (i = 0; i < t.size(); i++)
{
if (t[i] != '#')
{
t_temp += t[i];
}
else
{
if (t_temp.size() == 0)
{
}
else
{
t_temp.erase(t_temp.size()-1, 1);
}
}
}
if (s_temp == t_temp)
return true;
}
};
int main()
{
Solution s1;
if (s1.backspaceCompare("##ab#c", "ac"))
{
cout << "excellent" << endl;
}
return 0;
}
504.七进制数
给定一个整数,将其转化为7进制,并以字符串形式输出
就是使用循环,可以用to_string函数将整型转为字符型。
还有,需要注意整数的正负号。
/*给定一个整数,将其转化为7进制,并以字符串形式输出。*/
#include<iostream>
using namespace std;
#include<algorithm>
#include<string>
class Solution {
public:
string convertToBase7(int num) {
string newNum;
int temp, flag = 0; //flag是标志,如果为0,说明是正数
if (num == 0)
{
return "0";
}
if (num < 0)
{
num = -num; //将num转为正数
flag = 1;
}
while (num)
{
temp = num % 7;
newNum += (to_string(temp));
num /= 7;
}
reverse(newNum.begin(), newNum.end());
if (!flag)
{
return newNum;
}
else
{
return "-" + newNum;
}
}
};
int main()
{
Solution s1;
cout << s1.convertToBase7(100) << endl;
return 0;
}
682.棒球比赛
你现在是一场采用特殊赛制棒球比赛的记录员。这场比赛由若干回合组成,过去几回合的得分可能会影响以后几回合的得分。
比赛开始时,记录是空白的。你会得到一个记录操作的字符串列表 ops,其中 ops[i] 是你需要记录的第 i 项操作,ops 遵循下述规则:
整数 x - 表示本回合新获得分数 x
“+” - 表示本回合新获得的得分是前两次得分的总和。题目数据保证记录此操作时前面总是存在两个有效的分数。
“D” - 表示本回合新获得的得分是前一次得分的两倍。题目数据保证记录此操作时前面总是存在一个有效的分数。
“C” - 表示前一次得分无效,将其从记录中移除。题目数据保证记录此操作时前面总是存在一个有效的分数。
请你返回记录中所有得分的总和。
示例 1:
输入:ops = [“5”, “2”, “C”, “D”, “+”]
输出:30
解释:
“5” - 记录加 5 ,记录现在是[5]
“2” - 记录加 2 ,记录现在是[5, 2]
“C” - 使前一次得分的记录无效并将其移除,记录现在是[5].
“D” - 记录加 2 * 5 = 10 ,记录现在是[5, 10].
“+” - 记录加 5 + 10 = 15 ,记录现在是[5, 10, 15].
所有得分的总和 5 + 10 + 15 = 30
就是利用栈这个数据结构,遍历字符串数组,如果是数字就将其转换为整型入栈,这里学到了新的函数atoi(string)(),能使字符串转换为整型。如果是D,C,+ 。依次进行处理,现在就是我写的代码它不会按顺序运行,不知道错在哪了。先放一个错误的代码,再放一个正确的代码,以后会了就改正过来。
/*错误的*/
#include<iostream>
using namespace std;
#include<vector>
#include<string>
#include<stack>
class Solution {
public:
int calPoints(vector<string>& ops) {
stack<int>temp;
int i,n1 = 0, n2 = 0;
for (i = 0; i < ops.size(); i++)
{
if (ops[i] == "C")
{
temp.pop();
}
if (ops[i] == "D")
{
temp.push(temp.top() * 2);
}
if (ops[i] == "+")
{
n1 = temp.top();
temp.pop();
n2 = temp.top();
temp.push(n1);
temp.push(n1 + n2);
}
else
{
temp.push(atoi(ops[i].c_str())); //将字符串改为整型
}
}
int sum = 0;
while (!temp.empty())
{
sum += temp.top();
temp.pop();
}
return sum;
}
};
int main()
{
vector<string>ops;
ops.push_back("5");
ops.push_back("2");
ops.push_back("C");
ops.push_back("D");
ops.push_back("+");
Solution s1;
int temp = s1.calPoints(ops);
cout <<temp<< endl;
}
//正确的。
class Solution {
public:
int calPoints(vector<string>& ops) {
stack<int> nums;
for (string& s : ops) //这个只是遍历字符串数组
{
// cout << s << " " << nums.size() << endl;
if (s == "+")
{
// 这里要记得把弹出来的数字先插回去
int n1 = nums.top();
nums.pop();
int n2 = nums.top();
nums.push(n1);
nums.push(n1+n2);
}
else if (s == "D")
{
nums.push(nums.top() * 2);
}
else if (s == "C")
{
nums.pop();
}
else
{
nums.push(stoi(s));
}
}
// 累加和获得结果
int res = 0;
while (!nums.empty())
{
res += nums.top();
nums.pop();
}
return res;
}
};
121.买卖股票的最佳时机
给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。
你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。
返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0
解法:
首先想到的就是暴力解法,两个for循环,第一个循环是遍历数组,即买入价格,然后第二个for循环遍历买入这天之后的所有天数,找到差值最大,并赋值给maxProfit,但是在力扣上会超出时间限制。
改用第二种方法,只需要遍历一次,设置变量minPrice ,maxProfit,遍历时,先确定 当前价与当前最低价的差 和 当前maxProfit ,并将最大值赋给maxProfit ,这就是当前的最大利润,之后再 min(minPrice,prices),确定当前的最低价格。
之前调试的时候,我一直以为max函数是将比较得到的最大值赋值给第一个参数,这搞得我一直想问错哪了。此处省略一万字。
/*给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。
你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。
返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0 。
示例 1:
输入:[7, 1, 5, 3, 6, 4]
输出:5
解释:在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6 - 1 = 5 。
注意利润不能是 7 - 1 = 6, 因为卖出价格需要大于买入价格;同时,你不能在买入前卖出股票。*/
#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
/*class Solution { //这是两个for循环的做法
public:
int maxProfit(vector<int>& prices) {
int i, j, buyPrice, sellPrice;
int maxProfit=0;
for (i = 0; i < prices.size(); i++)
{
buyPrice = prices[i];
sellPrice = prices[i];
for (j = i + 1; j < prices.size(); j++)
{
if (prices[j] > sellPrice)
{
sellPrice = prices[j];
}
}
if (sellPrice - buyPrice > maxProfit)
{
maxProfit = sellPrice - buyPrice;
}
}
return maxProfit;
}
};*/
class Solution {
public:
int maxProfit(vector<int>& prices) {
int minPrice = 10000, maxprofit = 0;
int i;
for (i = 0; i < prices.size(); i++)
{
maxprofit = max(maxprofit, prices[i] - minPrice);
minPrice = min(minPrice, prices[i]);
}
return maxprofit;
}
};
int main()
{
vector<int>ch;
ch.push_back(7);
ch.push_back(1);
ch.push_back(5);
ch.push_back(3);
ch.push_back(6);
ch.push_back(4);
Solution s1;
cout << s1.maxProfit(ch) << endl;
return 0;
}
122.买卖股票的最佳时机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 。
#include<iostream>
using namespace std;
#include<vector>
class Solution {
public:
int maxProfit(vector<int>& prices) {
vector<int>profit;
int i;
for (i = 0; i < prices.size()-1; i++)
{
if (prices[i + 1] - prices[i]>0) //因为是不限制交易次数的,只要后面那天大于前天就说明有利可图
{
profit.push_back(prices[i + 1] - prices[i]);
}
}
int sum = 0;
for (i = 0; i < profit.size(); i++)
{
sum += profit.at(i);
}
return sum;
}
};
int main()
{
return 0;
}
868.二进制间距
给定一个正整数 n,找到并返回 n 的二进制表示中两个 相邻 1 之间的 最长距离 。如果不存在两个相邻的 1,返回 0 。
如果只有 0 将两个 1 分隔开(可能不存在 0 ),则认为这两个 1 彼此 相邻 。两个 1 之间的距离是它们的二进制表示中位置的绝对差。例如,“1001” 中的两个 1 的距离为 3 。
示例 1:
输入:n = 22
输出:2
解释:
22 的二进制是 “10110” 。
在 22 的二进制表示中,有三个 1,组成两对相邻的 1 。
第一对相邻的 1 中,两个 1 之间的距离为 2 。
第二对相邻的 1 中,两个 1 之间的距离为 1 。
答案取两个距离之中最大的,也就是 2 。
思路,先将这个整数转为字符串表示的二进制数,然后遍历二进制数,用容器存放1的位置,这里也可以用栈来存放,主要是求相邻两个数的差。时间复杂度是o(n)
/*给定一个正整数 n,找到并返回 n 的二进制表示中两个 相邻 1 之间的 最长距离 。如果不存在两个相邻的 1,返回 0 。
如果只有 0 将两个 1 分隔开(可能不存在 0 ),则认为这两个 1 彼此 相邻 。两个 1 之间的距离是它们的二进制表示中位置的绝对差。例如,"1001" 中的两个 1 的距离为 3 。
示例 1:
输入:n = 22
输出:2
解释:
22 的二进制是 "10110" 。
在 22 的二进制表示中,有三个 1,组成两对相邻的 1 。
第一对相邻的 1 中,两个 1 之间的距离为 2 。
第二对相邻的 1 中,两个 1 之间的距离为 1 。
答案取两个距离之中最大的,也就是 2 。*/
#include<iostream>
using namespace std;
#include<string>
#include<algorithm>
#include<vector>
class Solution {
public:
int binaryGap(int n) {
string newNum; //存放二进制数
int temp;
while (n) //将数转换为二进制
{
temp = n % 2;
n /= 2;
newNum += to_string(temp);
}
reverse(newNum.begin(), newNum.end());
vector<int>positionOne; //创建一个容器存放1的位置
int i, max = 0;
for (i = 0; i < newNum.length(); i++)
{
if (newNum[i] == '1')
{
positionOne.push_back(i);
}
}
if (positionOne.size()<=1) //没有相邻的1,直接返回
return 0;
for (i = 0; i < positionOne.size()-1; i++)
{
if (positionOne[i + 1] - positionOne[i] > max)
max = positionOne[i + 1] - positionOne[i];
}
return max;
}
};
int main()
{
Solution s;
cout << s.binaryGap(22) << endl;
return 0;
}
693.交替位二进制数
给定一个正整数,检查它的二进制表示是否总是 0、1 交替出现:换句话说,就是二进制表示中相邻两位的数字永不相同。
示例 1:
输入:n = 5
输出:true
解释:5 的二进制表示是:101
思路:转换为二进制数,用字符串,然后遍历字符串,看相邻的两个数是否相等,有相等就输出false
/*给定一个正整数,检查它的二进制表示是否总是 0、1 交替出现:换句话说,就是二进制表示中相邻两位的数字永不相同。
示例 1:
输入:n = 5
输出:true
解释:5 的二进制表示是:101*/
#include<iostream>
using namespace std;
#include<string>
class Solution {
public:
bool hasAlternatingBits(int n) {
string binNum;
int temp = 0;
while (n)
{
temp = n % 2;
n /= 2;
binNum += to_string(temp);
}
reverse(binNum.begin(), binNum.end());
int i;
for (i = 0; i < binNum.size()-1; i++)
{
if (binNum[i] == binNum[i + 1]) //只要有一个相等就返回false
return false;
}
return true; //循环能结束就返回true;
}
};