41.找出丢失的最小正整数
Given [1,2,0]
return 3
,
and [3,4,-1,1]
return 2
.
要求用固定大小的空间,以及O(n)
我的解法一:
//添加了辅助项0,后来发现这个方法时间复杂度是O(nlogn),重新做的方法见解法二:
class Solution {
public:
int firstMissingPositive(vector<int>& nums) {
nums.push_back(0);//加一项0为了确保为避免【-5,100】这种情况会输出-4
sort(nums.begin(),nums.end());
if(nums.size()<1||nums[0]>1)return 1;
for(int i=1;i<nums.size();++i){
if(nums[i]-nums[i-1]>1&&nums[i-1]>=0)return nums[i-1]+1;
}
return nums[nums.size()-1]+1;
}
};
class Solution {
public:
int firstMissingPositive(vector<int>& nums) {
unordered_map<int,int>mapping;
for(int i=0;i<nums.size();++i){
mapping[nums[i]]++;
}
for(int i=1;i<nums.size()+2;++i){
if (mapping[i]<1)return i;
}
return 1;
}
};
42.计算蓄水容量
Given [0,1,0,2,1,0,1,3,2,1,2,1]
, return 6
.
我的解法:【击败了60%】
解决思路:找到最高的板子,那么填满之后肯定是一个不降的序列以及一个不增的序列组成,对应填满即可。
注意,比较大小std::max(t1,t2) 要加上std不然报错……尴尬
class Solution {
public:
int trap(vector<int>& height) {
//思路:找到最高的,然后就是标准的先升再降了
int result=0;
int max=0,location=0;
for(int i=0;i<height.size();i++){
if(height[i]>max){
max=height[i];
location=i;
}
}
int begin=0;
//升序的算一下
for(int i=0;i<location;++i){
begin=std::max(height[i],begin);
if(height[i]<begin)result+=begin-height[i];
}
begin=0;
for(int i=height.size()-1;i>location;--i){
begin=std::max(height[i],begin);
if(height[i]<begin)result+=begin-height[i];
}
return result;
}
};
43.两个字符串表示的数字相乘
规则:长度都小于110,包括0-9,头部不为0,不能直接转为int
我的解法://很单纯地一位一位拆开算了…用了倒置解决了相加的问题,再用加实现了乘……【只击败了0.38%的人】
注意string的倒置的reverse也是要reverse(string.begin(),string.end());
class Solution {
public:
string multiply(string num1, string num2) {
string result = "";
if(num1=="0"||num2=="0")return "0";
// num2.reverse();
reverse(num2.begin(), num2.end());//再次强调,reverse是STL里的,不是string的成员函数
string zero = "";
for (int i = 0; i<num2.size(); ++i) {
string temp = multiply2(atoi(num2.substr(i,1).c_str()), num1) + zero;
result = add(temp, result);
zero += "0";
}
return result;
}
string multiply2(int n, string num) {
string result = "";
for (int i = 0; i<n; ++i) {
result = add(result, num);
}
return result;
}
string add(string num1, string num2) {
string result = "";
reverse(num1.begin(), num1.end());
reverse(num2.begin(), num2.end());
int max = std::max(num1.size(), num2.size());
int add = 0, add1 = 0, add2 = 0;
for (int i = 0; i<max + 1; i++) {
if (i<num1.size())add1 = atoi(num1.substr(i, 1).c_str()); else add1 = 0;
if (i<num2.size())add2 = atoi(num2.substr(i, 1).c_str()); else add2 = 0;
int result1 = (add1 + add2 + add) % 10;
add = (add1 + add2 + add) / 10;
if (i != max || (i == max&&result1 == 1)) result += to_string(result1);
}
reverse(result.begin(), result.end());
return result;
}
};
别人的不需要reverse的简洁的解法://我还是太耿直了
//用num1[i]-'0'表示大小确实挺方便
//又看了一遍,确实精巧,和我们算乘法反的,但好简洁……
string multiply(string num1, string num2) {
string sum(num1.size() + num2.size(), '0');
for (int i = num1.size() - 1; 0 <= i; --i) {
int carry = 0;
for (int j = num2.size() - 1; 0 <= j; --j) {
int tmp = (sum[i + j + 1] - '0') + (num1[i] - '0') * (num2[j] - '0') + carry;
sum[i + j + 1] = tmp % 10 + '0';
carry = tmp / 10;
}
sum[i] += carry;
}
size_t startpos = sum.find_first_not_of("0");
if (string::npos != startpos) {
return sum.substr(startpos);
}
return "0";
}
44.检测是否匹配(? * 匹配,做了好久,过阵子要在看看,DP搜索肯定方便点)
?可以代表一个字母,*可以代表任意长度的字母
isMatch("aa","a") → false isMatch("aa","aa") → true isMatch("aaa","aa") → false isMatch("aa", "*") → true isMatch("aa", "a*") → true isMatch("ab", "?*") → true isMatch("aab", "c*a*b") → false
终于做完了……花了好久好久……【击败了75%】
我的做法:把所有*提取出来,再分段检测匹配是否一样…同时要写一个isSame函数检测两个不含有*的string是否匹配
class Solution {
public:
bool isSame(string s, string p) {
if (p.size() == 0 && s.size() == 0)return true;
if (s.size() == p.size()) {
for (int i = 0; i<s.size(); ++i) {
if (s[i] == p[i] || p[i] == '?') {}
else return false;
}
}
else return false;
return true;
}
bool isMatch(string s, string p) {
vector<int>star;
for (int i = 0; i<p.size(); ++i) {
if (p[i] == '*')star.push_back(i);
}
if (star.size() == 0)return isSame(s, p);
int total = s.size() - p.size() + star.size();
if (total<0)return false;
bool result = true;
int begin = 0;
for (int i = 0; i<star.size() + 1; ++i) {
string temp = "";
if (i == 0 && star[i] == 0)++i;
if (i == 0) { temp = p.substr(0, star[i]); if (isSame(s.substr(0, temp.size()), temp)) { begin = temp.size(); continue; } else return false; }
else if (i == star.size()) {
if (star[i - 1] == p.size() - 1)temp = "";
else
temp = p.substr(star[i - 1] + 1, p.size() - star[i - 1] - 1);
if (isSame(s.substr(s.size() - temp.size(), temp.size()), temp) || temp.size() == 0) { return true; }
else return false;
}
else {
if (i<star.size() - 1 && star[i - 1] + 1 == star[i])continue;
else
temp = p.substr(star[i - 1] + 1, star[i] - star[i - 1] - 1);
temp = p.substr(star[i - 1] + 1, star[i] - star[i - 1] - 1);
}
bool temp_result = false;
int total1 = total;
for (int ii = begin; ii<begin + total1 + 1; ++ii) {
if (isSame(s.substr(ii, temp.size()), temp)) { begin = ii + temp.size(); temp_result = true; break; }
else { --total; }
}
if (!temp_result)return false;
}
return result;
}
};
45.跳跳棋
每个int代表下一步可以往后运动的步长,下面这种只击败了0.61%
class Solution {
public:
int jump(vector<int>& nums) {
int result=1;
if(nums.size()==0||nums.size()==1)return 0;
for(int i=0;i<nums.size();++i){
nums[i]+=i;
}
int begin=0;
while(nums[begin]<nums.size()-1){
begin=max(nums,begin,nums[begin]);
result++;
}
return result;
}
int max(vector<int>nums,int begin,int end){
int result=begin;
for(int i=begin;i<end+1;++i){
if(nums[result]<nums[i])result=i;
}
return result;
}
};
46.找出全排列//next_permutations
例如
[1,2,3]
have the following permutations:
[ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1] ]
class Solution {
public:
vector<vector<int>> permute(vector<int>& nums) {
vector<vector<int>>result;
sort(nums.begin(),nums.end());
if(nums[0]==nums[nums.size()-1]){result.push_back(nums);return result;}//防止【1】这种情况
int flag=nums[0];int goon=1;
while(1){
result.push_back(nums);
next_permutation(nums.begin(),nums.end());
if(nums[0]!=flag)goon=0;
if(nums[0]==flag&&goon==0)break;
}
return result;
}
};
47.返回所有的全排列(这回可能有重复)
//但是我做上一题的时候貌似就包括可能有重复的情况,所有代码和上一题一样就通过了……
class Solution {
public:
vector<vector<int>> permuteUnique(vector<int>& nums) {
vector<vector<int>>result;
sort(nums.begin(),nums.end());
if(nums[0]==nums[nums.size()-1]){result.push_back(nums);return result;}//防止【1】这种情况
int flag=nums[0];int goon=1;
while(1){
result.push_back(nums);
next_permutation(nums.begin(),nums.end());
if(nums[0]!=flag)goon=0;
if(nums[0]==flag&&goon==0)break;
}
return result;
}
};
48.矩阵顺时针旋转90度
class Solution {
public:
void rotate(vector<vector<int>>& matrix) {
int size=(matrix.size()+1)/2;
int length=matrix.size()-1;
for(int i=0;i<size;++i){
for(int j=i;j<length-i;++j){
int temp=matrix[i][j];
matrix[i][j]=matrix[length-j][i];
matrix[length-j][i]=matrix[length-i][length-j];
matrix[length-i][length-j]=matrix[j][length-i];
matrix[j][length-i]=temp;
}
}
return;
}
};
49.颠倒字母重新分组 //auto,set/multiset,以及multiset给vector赋值
着重关注,这里用到了用法 auto, set/multiset<类型> , 以及Vector的另一种初始化……利用multiset<string>给vector<string>初始化……
class Solution {
public:
vector<vector<string>> groupAnagrams(vector<string>& strs) {
unordered_map<string, multiset<string>>mapping;
for (int i = 0; i<strs.size(); ++i) {
string temp = strs[i];
sort(temp.begin(), temp.end());
mapping[temp].insert(strs[i]);
}
vector<vector<string>>result;
for (auto m : mapping) {
//这里的返回的是std::pair,第一个代表前面的,第二个代表后面的
//下面是Vector<类型>的另一种初始化方式 temp(另一个)
vector<string> temp (m.second.begin(), m.second.end());
result.push_back(temp);
}
return result;
}
};
50.计算pow(x,n) //n次方
这里要注意,n可能为负的!!!
class Solution {
public:
double myPow(double x, int n) {
if (n == 0) return 1;
double t = myPow(x, n / 2);
if (n % 2) {
return n<0 ? 1 / x*t*t : x*t*t;
}
else {
return t*t;//少计算了一次myPow,碉堡
}
}
};
如果用下面这段代码:
class Solution {
public:
double myPow(double x, int n) {
if (n == 1 )return x;
if (n == -1)return 1 / x;
if(n==0)return 1;
//二分法
return myPow(x, n / 2)*myPow(x, n - n / 2);
}
};
下面的例子会超时间 0.00001 2147483647
所以上面的还是很厉害的……
最近题目做得少了…………