自定义排序
- 快排
- 内置函数
-
快排
class Solution {
public:
string minNumber(vector<int>& nums) {
vector<string> strs;
for(int i=0;i<nums.size();++i)
{
strs.push_back(to_string(nums[i]));
}
quickSort(strs,0,strs.size()-1);
string res;
for(string s:strs)
res.append(s);
return res;
}
private:
void quickSort(vector<string>& strs,int left,int right)
{
if(left>=right) return;
int i=left,j=right;
while(i<j)
{
while(strs[j]+strs[left]>=strs[left]+strs[j] && i<j) j--;
while(strs[i]+strs[left]<=strs[left]+strs[i] && i<j) i++;
swap(strs[i],strs[j]);
}
swap(strs[i],strs[left]);
quickSort(strs,left,i-1);
quickSort(strs,i+1,right);
}
};
-
内置函数
class Solution {
public:
string minNumber(vector<int>& nums) {
vector<string> strs;
string res;
for(int i=0;i<nums.size();++i)
strs.push_back(to_string(nums[i]));
sort(strs.begin(),strs.end(),[](string& x,string& y){return x+y<y+x;});
for(int i=0;i<strs.size();++i)
{
res.append(strs[i]);
}
return res;
}
};
动态规划!
-
字符串遍历!
class Solution {
public:
int translateNum(int num) {
string s=to_string(num);
int a=1,b=1;
for(int i=1;i<s.size();++i)
{
auto temp=s.substr(i-1,2);
int c=0;
if(temp>="10"&& temp<="25")
{
c=a+b;
}
else
c=b;
a=b;
b=c;
}
return b;
}
};
c++知识点: String 的 substr(pos,len); 前者是起始位置,后者是子串长度
-
数字求余
- 每次只需要两个值 同时保存的变量也是两个值
class Solution {
public:
int translateNum(int num) {
int a=1,b=1,x,y=num%10;
while(num!=0)
{
num/=10;
x=num%10;
int temp=10*x+y;
y=x;
int c;
if(temp>=10 && temp<=25)
c=a+b;
else
c=b;
a=b;
b=c;
}
return b;
}
};
动态规划!
class Solution {
public:
int maxValue(vector<vector<int>>& grid) {
int row,rows=grid.size();
int col,cols=grid[0].size();
int res=grid[0][0];
for(row=0;row<rows;++row)
{
for(col=0;col<cols;++col)
{
if(row==0)
{
if(col!=0)
{
grid[row][col]+=grid[row][col-1];
res=max(res,grid[row][col]);
}
continue;
}
if(col==0)
{
grid[row][col]+=grid[row-1][col];
res=max(res,grid[row][col]);
continue;
}
grid[row][col]+=max(grid[row][col-1],grid[row-1][col]);
res=max(res,grid[row][col]);
}
}
return res;
}
};
动态规划
之前做过,用的是 unordered_set+滑动窗口(其实就是动态规划的思想)
这里有一个细节,re.erase(left) 为什么用的left,而没有用 re.begin(),因为re.begin()指向最后一个进去的元素!
class Solution {
public:
int lengthOfLongestSubstring(string s) {
unordered_set<char> re;
int left=0,right=0;
int res=0;
while(right<s.size())
{
if(!re.count(s[right]))
{
re.insert(s[right]);
}
else
{
while(re.count(s[right]))
{
re.erase(s[left]);
++left;
}
re.insert(s[right]);
}
res=max(right-left+1,res);
++right;
}
return res;
}
};
动态规划+!
其实推导上不好理解,但是看ppt的动画还不错。
为什么+1?因为每一个丑数 必然是下一个丑数的2、3、5倍,因此不能遗漏,每个数的2、3、5倍都要过一遍!
为了排序 每次加最小的!
class Solution {
public:
int nthUglyNumber(int n) {
int a=0,b=0,c=0;
int dp[n];
dp[0]=1;
for(int i=1;i<n;++i)
{
int n2=dp[a]*2,n3=dp[b]*3,n5=dp[c]*5;
dp[i]=min(min(n2,n3),n5);
if(dp[i]==n2) a++;
if(dp[i]==n3) b++;
if(dp[i]==n5) c++;
}
return dp[n-1];
}
};
暴力法 O(n^2)
hash表 O(n):涉及到查找的一定要考虑hash
class Solution {
public:
char firstUniqChar(string s) {
map<char,int> hash;
for(int i=0;i<s.size();++i)
{
if(hash.count(s[i]))
{
++hash[s[i]];
}
else
{
hash[s[i]]=1;
}
}
for(int i=0;i<s.size();++i)
{
if(hash[s[i]]==1)
return s[i];
}
return ' ';
}
};
暴力法 超时。
归并排序 困难题放弃了,看题解吧
class Solution {
public:
int reversePairs(vector<int>& nums) {
vector<int> tmp(nums.size());
return mergeSort(0,nums.size()-1,nums,tmp);
}
private:
int mergeSort(int left,int right,vector<int>& nums,vector<int>& tmp)
{
//终止条件
if(left>=right) return 0;
//递归划分
int m=(left+right)/2;
int res=mergeSort(left,m,nums,tmp) + mergeSort(m+1,right,nums,tmp);
//合并阶段
int i=left,j=m+1;
for(int k=left;k<=right;k++)
tmp[k]=nums[k];
for(int k=left;k<=right;k++)
{
if(i== m+1)
nums[k]=tmp[j++];
else if(j==right+1||tmp[i]<=tmp[j])
nums[k]=tmp[i++];
else{
nums[k]=tmp[j++];
res+=m-i+1;
}
}
return res;
}
};
拿到题用 hash做出来了,没什么难度。
看题解发现 用的“双指针”!!秒到家了
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode*A=headA,*B=headB;
while(A!=B)
{
A=A!=NULL? A->next:headB;
B=B!=NULL? B->next:headA;
}
return A;
}
};
二分查找
别人的代码写的是真的简洁!
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0, right = nums.size() - 1, mid, count = 0;
while (left <= right) {
mid = (left + right) / 2;
if (nums[mid] < target) left = mid + 1;
else if (nums[mid] > target) right = mid - 1;
else {
count++;
left = mid;
break;
}
}
if (count > 0) {
int i = left - 1, j = left + 1;
while (i >= 0 && nums[i] == target) {
count++;
i--;
}
while (j < nums.size() && nums[j] == target) {
count++;
j++;
}
}
return count;
}
};
上面的算法时间复杂度容易到O(n), 下面的就是O(logn)
class Solution {
public:
int search(vector<int>& nums, int target) {
// 搜索右边界 right
int i = 0, j = nums.size() - 1;
while(i <= j) {
int m = (i + j) / 2;
if(nums[m] <= target) i = m + 1;
else j = m - 1;
}
int right = i;
// 若数组中无 target ,则提前返回
if(j >= 0 && nums[j] != target) return 0;
// 搜索左边界 right
i = 0; j = nums.size() - 1;
while(i <= j) {
int m = (i + j) / 2;
if(nums[m] < target) i = m + 1;
else j = m - 1;
}
int left = j;
return right - left - 1;
}
};
遍历O(n)直接AC
二分 写了半天 最后发现判断条件 mid没加1
class Solution {
public:
int missingNumber(vector<int>& nums) {
//二分
int left=0,right=nums.size()-1;
int mid=right/2;
while(left<=right )
{
mid=(left+right)/2;
if(mid==nums[mid])
left = mid+1;
else
{
right = mid-1;
}
}
return left;
}
};
中序遍历 直接AC
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> res;
int kthLargest(TreeNode* root, int k) {
inorder(root);
return res[res.size()-k];
}
void inorder(TreeNode* root)
{
if(root==NULL)
return;
inorder(root->left);
res.push_back(root->val);
inorder(root->right);
}
};
二叉树里 递归太妙了
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int maxDepth(TreeNode* root) {
if(root==NULL)
return 0;
int n_left=maxDepth(root->left);
int n_right=maxDepth(root->right);
return n_left>n_right? (n_left+1):(n_right+1);
}
};