1. 整数反转
题目:https://leetcode-cn.com/problems/reverse-integer/
注意:res=res*10+pop;可能存在溢出问题。
class Solution {
public:
int reverse(int x) {
int res=0;
int pop=0;
while(x!=0){
pop = x % 10;
x /= 10;
if(res > INT_MAX/10 || (res == INT_MAX/10 && pop > 7)){
return 0;
}
if(res < INT_MIN/10 ||(res==INT_MIN/10 && pop<-8)){
return 0;
}
res=res*10+pop;
}
return res;
}
};
2. 反转字符串
题目:https://leetcode-cn.com/problems/reverse-string/
思路: 双指针法是使用两个指针,一个左指针 left,右指针 right,开始工作时 left 指向首元素,right 指向尾元素。交换两个指针指向的元素,并向中间移动,直到两个指针相遇。
class Solution {
public:
void reverseString(vector<char>& s) {
int left=0, right=s.size()-1;
while(left<right){
int tmp=s[left];
s[left]=s[right];
s[right]=tmp;
left++;
right--;
}
}
};
3. 回文数
题目:https://leetcode-cn.com/problems/palindrome-number/
思路: (1) 转成字符串,并检查字符串是否为回文。但是,这需要额外的非常量空间来创建问题描述中所不允许的字符串。
(2)反转整数,判断和原数是否相同,但是存在溢出问题。
(3) 反转一半数字
首先,我们应该处理一些临界情况。所有负数都不可能是回文,除了 0 以外,所有个位是 0 的数字不可能是回文,因为最高位不等于 0。所以我们可以对所有大于 0 且个位是 0 的数字返回 false。
我们如何知道反转数字的位数已经达到原始数字位数的一半?
由于整个过程我们不断将原始数字除以 10,然后给反转后的数字乘上 10,所以,当原始数字小于或等于反转后的数字时,就意味着我们已经处理了一半位数的数字了。
class Solution {
public:
bool isPalindrome(int x) {
if(x<0 || (x%10==0 && x!=0)){
return false;
}
int reversenum=0;
while(x>reversenum){
reversenum = reversenum*10 + x%10;
x /= 10;
}
return x==reversenum || x==reversenum/10;
}
};
4. 最长公共前缀
题目:https://leetcode-cn.com/problems/longest-common-prefix/
思路:纵向比较
class Solution {
public:
string longestCommonPrefix(vector<string>& strs) {
if(strs.size()==0){
return "";
}
int length=strs[0].size(); //列数
int count=strs.size(); //行数
for(int i=0; i<length; i++){
char c=strs[0][i];
for(int j=1; j<count; j++){
if(i==strs[j].size() || strs[j][i]!=c){
return strs[0].substr(0,i);
}
}
}
return strs[0];
}
};
*/
class Solution {
public:
string longestCommonPrefix(vector<string>& strs) {
string res = strs.empty()? "" : strs[0];
for(auto s:strs){
//s.find(res) != 0不是其前缀,开始减去res的最后一个字符
while(s.find(res)!= 0) res=res.substr(0,res.size()-1);
}
return res;
}
};
5. 下一个排列
题目:https://leetcode-cn.com/problems/next-permutation/
思路:
- 我们希望下一个数比当前数大,这样才满足“下一个排列”的定义。因此只需要将后面的「大数」与前面的「小数」交换,就能得到一个更大的数。比如 123456,将 5 和 6 交换就能得到一个更大的数 123465。
- 我们还希望下一个数增加的幅度尽可能的小,这样才满足“下一个排列与当前排列紧邻“的要求。为了满足这个要求,我们需要:
- 在尽可能靠右的低位进行交换,需要从后向前查找
- 将一个 尽可能小的「大数」 与前面的「小数」交换。比如 123465,下一个排列应该把 5 和 4 交换而不是把 6 和 4 交换
- 将「大数」换到前面后,需要将「大数」后面的所有数重置为升序,升序排列就是最小的排列。以 123465 为例:首先按照上一步,交换 5 和 4,得到 123564;然后需要将 5 之后的数重置为升序,得到 123546。显然 123546 比 123564 更小,123546 就是 123465 的下一个排列
class Solution {
public:
void nextPermutation(vector<int>& nums) {
if(nums.empty()) return;
int i=nums.size()-2;
while(i>=0 && nums[i]>=nums[i+1]){
i--;
}
if(i>=0){
int j=nums.size()-1;
while(j>=0 && nums[j]<=nums[i]){
j--;
}
swap(nums,i,j);
}
reverse(nums,i+1);
}
void swap(vector<int> &nums, int i, int j){
int tmp=nums[i];
nums[i]=nums[j];
nums[j]=tmp;
}
void reverse(vector<int> & nums, int i){
int j=nums.size()-1;
while(i<j){
swap(nums,i,j);
j--;
i++;
}
}
};