目录
1.数组
1.1 给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。
不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。
class Solution {
public:
int removeDuplicates(vector<int>& nums)
{
int i=!nums.empty();
for(int n:nums)
{
if(n>nums[i-1])
{
nums[i]=n;
i++;
}
}
return i;
}
};
1.2 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。
class Solution {
public:
int maxProfit(vector<int>& prices)
{
int k=-1;
vector<int> re_prices;
for(int m:prices)
{
if(m!=k)
{
re_prices.push_back(m);
k=m;
}
}
prices=re_prices;
int min=-1,max=-1;
int sum=0;
if( prices.size()==2) if(prices[1]>prices[0]) sum=prices[1]-prices[0];
if( prices.size()>=3)
{
if(prices[0]<=prices[1]) min=prices[0];
for(int i=1;i<prices.size();i++)
{
if(prices[i]<prices[i-1] && prices[i]<prices[i+1]) min=prices[i];
if(prices[i]>prices[i-1] && prices[i]>prices[i+1]) max=prices[i];
if(prices[i]>prices[i-1] && i==prices.size()-1) max=prices[i];
if(min!=-1 && max!=-1)
{
sum=sum+max-min;
min=-1;
max=-1;
}
}
}
return sum;
}
};
1.3 给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。
class Solution {
public:
void rotate(vector<int>& nums, int k)
{
vector<int> re_nums;
k=k%nums.size();
int seed=nums.size()-k;
if(seed>0)
{
for(int i=seed;i<nums.size();i++)
re_nums.push_back(nums[i]);
for(int i=0;i<seed;i++)
re_nums.push_back(nums[i]);
nums=re_nums;
}
}
};
1.4 给定一个整数数组,判断是否存在重复元素。
如果任何值在数组中出现至少两次,函数返回 true。如果数组中每个元素都不相同,则返回 false。
class Solution {
public:
bool containsDuplicate(vector<int>& nums)
{
int n=nums.size();
for(int i=0;i<n;i++)
{
int count=0;
for(int j=i+1;j<n;j++)
{
if(nums[i]==nums[j]) return true;
}
}
return false;
}
};
1.5 给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明: 你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
class Solution {
public:
int singleNumber(vector<int>& nums)
{
int tem[nums.size()]={0};
for(int i=0;i<nums.size();i++)
{
for(int j=0;j<nums.size();j++)
{
if(nums[i]==nums[j]) tem[i]++;
if(tem[i]>1) break;
if(j==nums.size()-1 && tem[i]==1) return nums[i];
}
}
}
};
1.6 给定两个数组,编写一个函数来计算它们的交集。
class Solution {
public:
vector<int> intersect(vector<int>& nums1, vector<int>& nums2)
{
vector<int> result;
if(nums1.size()!=0 && nums2.size()!=0)
{
int tem1[nums1.size()]={0};
int tem2[nums2.size()]={0};
for(int i=0;i<nums1.size();i++)
{
for(int j=i;j<nums1.size();j++)
{
if(nums1[i]==nums1[j]) tem1[i]++;
}
}
for(int i=0;i<nums2.size();i++)
{
for(int j=i;j<nums2.size();j++)
{
if(nums2[i]==nums2[j]) tem2[i]++;
}
}
for(int i=0;i<nums1.size();i++)
for(int j=0;j<nums2.size();j++)
if(nums1[i]==nums2[j] && tem1[i]==tem2[j]) result.push_back(nums1[i]);
}
return result;
}
};
1.7 给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一。
最高位数字存放在数组的首位, 数组中每个元素只存储一个数字。
你可以假设除了整数 0 之外,这个整数不会以零开头
class Solution {
public:
vector<int> plusOne(vector<int>& digits)
{
int n=digits.size();
if(digits[n-1]<9)
{
digits[n-1]+=1;
return digits;
}
if(digits[n-1]==9)
{
int tem=0;
for(int i=0;i<n;i++,tem++) if(digits[n-1-i]!=9)
{
//tem++;
break;
}
if(tem==n)
{
vector<int> re(n+1,0);
re[0]=1;
digits = re;
}
else
{
for(int i=0;i<tem;i++) digits[n-1-i]=0 ;
digits[n-1-tem]+=1;
}
}
return digits;
}
};
1.8 给定一个数组 nums
,编写一个函数将所有 0
移动到数组的末尾,同时保持非零元素的相对顺序
class Solution {
public:
void moveZeroes(vector<int>& nums)
{
for(int i=0;i<nums.size();i++)
{
if(nums[i]==0 && nums[i+1]!=0 && i<nums.size()-1)
{
nums[i]=nums[i+1];
nums[i+1]=0;
int j=i;
while(nums[j-1]==0 && j-1>=0)
{
nums[j-1]=nums[j];
nums[j]=0;
j--;
}
}
}
}
};
1.9 给定一个整数数组和一个目标值,找出数组中和为目标值的两个数。
你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用。
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target)
{
for(int i=0;i<nums.size();i++)
{
for(int j=i+1;j<nums.size();j++)
{
if((nums[i]+nums[j])==target)
{
vector<int> result={i,j};
return result;
}
}
}
}
};
1.10 判断一个 9x9 的数独是否有效。只需要根据以下规则,验证已经填入的数字是否有效即可。
- 数字
1-9
在每一行只能出现一次。 - 数字
1-9
在每一列只能出现一次。 - 数字
1-9
在每一个以粗实线分隔的3x3
宫内只能出现一次
class Solution {
public:
bool isValidSudoku(vector<vector<char>>& board)
{
int tem_row[9][9]={0};
int tem_col[9][9]={0};
int tem_nine[9][9]={0};
vector<vector<char>> re_board(9);
for(int i=0;i<9;i++)
{
for(char m:board[i])
{
if(m!='.')
{
int index=m -'0' - 1;
tem_row[i][index]++;
}
}
for(int m:tem_row[i])
{
if(m>1) return false;
}
for(int j=0;j<9;j++)
{
if((int)board[j][i]!='.') tem_col[i][board[j][i]-'0'-1]++;
}
for(int m:tem_col[i])
{
if(m>1) return false;
}
}
for(int i=0;i<9;i++)
{
for(int j=0;j<9;j++)
{
re_board[j/3+3*(i/3)].push_back(board[i][j]);
}
}
for(int i=0;i<9;i++)
{
for(char m:re_board[i])
{
if(m!='.') tem_nine[i][m-'0'-1]++;
}
for(int m:tem_nine[i])
if(m>1) return false;
}
return true;
}
};
1.11 给定一个 n × n 的二维矩阵表示一个图像。
将图像顺时针旋转 90 度。
class Solution {
public:
void rotate(vector<vector<int>>& matrix)
{
int n=matrix.size();
if(n>0)
{
for(int i=0;i<n/2;i++)
{
for(int j=i;j<n-1-i;j++)
{
int tem=matrix[i][j];
matrix[i][j]=matrix[n-1-j][i];
matrix[n-1-j][i]=matrix[n-1-i][n-1-j];
matrix[n-1-i][n-1-j]=matrix[j][n-1-i];
matrix[j][n-1-i]=tem;
}
}
}
}
};
2.字符串
2.1 编写一个函数,其作用是将输入的字符串反转过来。
class Solution {
public:
string reverseString(string s)
{
string re_s(s);
int n=s.size();
int index=n-1;
for(int i=0;i<n;i++)
{
re_s[i]=s[index--];
}
return re_s;
}
};
2.2 给定一个 32 位有符号整数,将整数中的数字进行反转
class Solution {
public:
int reverse(int x)
{
int IN_MAX=2147483647;
bool is_negative=false;
if(x<0)
{
is_negative=true;
x=-x;
}
int count_num=0;
int copy=x;
while(copy>0)
{
count_num++;
copy=copy/10;
}
int sum=0;
if(count_num<10)
{
while(x>0)
{
int rem=x%10;
x=x/10;
sum=sum*10+rem;
}
}
else
{
while(x>10)
{
int rem=x%10;
x=x/10;
sum=sum*10+rem;
}
if(sum>IN_MAX/10 || (sum==IN_MAX/10 && x>7)) return 0;
else sum=sum*10+x;
}
return is_negative?sum*(-1):sum;
}
};
2.3 给定一个字符串,找到它的第一个不重复的字符,并返回它的索引。如果不存在,则返回 -1。
class Solution {
public:
int firstUniqChar(string s)
{
int n=s.size();
if(n==0)return -1;
int count[n]={0};
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
if(s[i]==s[j])count[i]++;
if(count[i]==2) break;
}
if(count[i]==1) return i;
}
return -1;
}
};
2.4 给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的一个字母异位词
class Solution {
public:
bool isAnagram(string s, string t)
{
if(s.size()!=t.size())return false;
int count_s[26]={0};
int count_t[26]={0};
for(int i=0;i<s.size();i++)
{
int num_s=s[i]-'a';
count_s[num_s]++;
int num_t=t[i]-'a';
count_t[num_t]++;
}
for(int i=0;i<26;i++)
{
if(count_s[i]!=count_t[i]) return false;
}
return true;
}
};
2.5 给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。
class Solution {
public:
bool isPalindrome(string s)
{
int n=0;
for(char &m:s)
{
if(isalnum(m))
{
n+=1;
if(isalpha(m)) m=tolower(m);
}
}
string s1(n,'a');
int k=0;
for(int i=0;i<s.size();i++)
{
if(isalnum(s[i])) s1[k++]=s[i];
}
string s2(s1);
for(int i=0;i<n;i++)
{
s2[i]=s1[n-1-i];
}
if(s1==s2)return true;
return false;
}
};
2.6 实现 atoi
,将字符串转为整数。
该函数首先根据需要丢弃任意多的空格字符,直到找到第一个非空格字符为止。如果第一个非空字符是正号或负号,选取该符号,并将其与后面尽可能多的连续的数字组合起来,这部分字符即为整数的值。如果第一个非空字符是数字,则直接将其与之后连续的数字字符组合起来,形成整数。
字符串可以在形成整数的字符后面包括多余的字符,这些字符可以被忽略,它们对于函数没有影响。
当字符串中的第一个非空字符序列不是个有效的整数;或字符串为空;或字符串仅包含空白字符时,则不进行转换。
若函数不能执行有效的转换,返回 0。
class Solution {
public:
int myAtoi(string str)
{
if(str.empty()) return 0;
int a;
int index_symbol=-1;
for(int i=0;i<str.size();i++)
{
char m=str[i];
if(m!=' ')
{
if(m=='-')
{
a=-1;
index_symbol=i;
}
else if(m=='+' || isdigit(m))
{
a=1;
if(m=='+') index_symbol=i;
}
else return 0;
break;
}
}
if(index_symbol!=-1)
{
if(!isdigit(str[index_symbol+1])) return 0;
}
int num_index=-1;
for(int i=0;i<str.size();i++)
{
if(isdigit(str[i]))
{
num_index=i;
break;
}
}
if(num_index==-1) return 0;
string numX;
for(int i=num_index;i<str.size();i++)
{
if(isdigit(str[i]))
{
numX+=str[i];
if(!isdigit(str[i+1])) break;
}
}
int nonzero_index=-1;
for(int i=0;i<numX.size();i++)
{
if(numX[i]=='0')continue;
nonzero_index=i;
break;
}
if(nonzero_index==-1) return 0;
string num;
for(int i=nonzero_index;i<numX.size();i++)
{
num+=numX[i];
}
int sum=0;
int n=num.size();
if(n<10)
{
for(int i=0;i<n;i++)
{
int tem=num[i]-'0';
sum=sum*10+tem;
}
}
else if(n>10)
{
if(a==-1)return INT_MIN;
else sum=INT_MAX;
}
else
{
for(int i=0;i<9;i++)
{
int tem=num[i]-'0';
sum=sum*10+tem;
}
if(sum>INT_MAX/10)
{
if(a==1)sum=INT_MAX;
else return INT_MIN;
}
else if(sum<INT_MAX/10)
{
int tem=num[9]-'0';
sum=sum*10+tem;
}
else
{
int tem=num[9]-'0';
if(tem<=7)
{
int tem=num[9]-'0';
sum=sum*10+tem;
}
else if(tem==8)
{
if(a==-1) return INT_MIN;
else return INT_MAX;
}
else
{
if(a==1)sum=INT_MAX;
else return INT_MIN;
}
}
}
return a*sum;
}
};
2.7 实现 strStr() 函数。
给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回 -1。
class Solution {
public:
int strStr(string haystack, string needle)
{
if(needle.empty())return 0;
int n=needle.size();
char arc=needle[0];
for(int i=0;i<haystack.size();i++)
{
if(haystack[i]==arc)
{
string s(n,arc);
int k=0;
for(int j=i;j<i+n;j++)
{
s[k++]= haystack[j];
}
if(s==needle) return i;
}
}
return -1;
}
};
2.8 报数序列是一个整数序列,按照其中的整数的顺序进行报数,得到下一个数。其前五项如下:
1. 1 2. 11 3. 21 4. 1211 5. 111221
1
被读作 "one 1"
("一个一"
) , 即 11
。11
被读作 "two 1s"
("两个一"
), 即 21
。21
被读作 "one 2"
, "one 1"
("一个二"
, "一个一"
) , 即 1211
。
给定一个正整数 n(1 ≤ n ≤ 30),输出报数序列的第 n 项。
注意:整数顺序将表示为一个字符串
class Solution {
public:
string countAndSay(int n)
{
string a="1";
string tem;
for(int i=1;i<n;i++)
{
int t=0;
while(t<a.size())
{
int value=1;
while(a[t]==a[t+1])
{
value++;
t++;
}
tem=tem+to_string(value)+a[t];
t++;
}
a=tem;
tem="";
}
return a;
}
};
2.9 编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 ""
。
class Solution {
public:
string longestCommonPrefix(vector<string>& strs)
{
if(strs.empty()) return string();
int min=999;
int n=strs.size();
for(int i=0;i<n;i++)
{
if(strs[i].size()>min) min=strs[i].size();
}
string common;
bool is_break=false;
for(int j=0;j<min;j++)
{
char tem=strs[0][j];
for(int i=0;i<n;i++)
{
if(tem==strs[i][j])
{
if(i==n-1) common+=tem;
}
else
{
is_break=true;
break;
}
}
if(is_break)break;
}
return common;
}
};