面试题37
这题演示是层序,但是功能要求是只要实现序列化和反序列化就可,所以题解的前序是可行的。
DFS
class Codec {
public:
// Encodes a tree to a single string.
void rserialize(TreeNode* root, string &s){
if(root==nullptr) s+="#,";//用#不用null,1个字符好处理点
else{
s += (to_string(root->val)+",");
rserialize(root->left, s);
rserialize(root->right, s);
}
}
string serialize(TreeNode* root) {
string s;
rserialize(root, s);
return s;
}
TreeNode* rdeserialize(list<string>& l){
if(l.front() == "#"){
l.erase(l.begin());
return nullptr;
}
TreeNode* root=new TreeNode(stoi(l.front()));
l.erase(l.begin());
root->left=rdeserialize(l);
root->right=rdeserialize(l);
return root;
}
// Decodes your encoded data to tree.
TreeNode* deserialize(string data) {
list<string> l;
string s;
for(char c:data){
if(c==','){
l.push_back(s);
s.clear();
}
else{
s+=c;
}
}
if(!s.empty()){
l.push_back(s);
s.clear();
}
return rdeserialize(l);
}
};
class Solution {
public:
string s;
int j=0;
void Srtial(TreeNode *root)
{
if(root==NULL)
{
s+="#!";
return ;
}
s+=to_string(root->val);
s+="!";
Srtial(root->left);
Srtial(root->right);
}
char* Serialize(TreeNode *root) {
Srtial(root);
return (char *)s.data();
}
TreeNode* Deserialize(char *str) {
s=str;
return Deserial();
}
TreeNode* Deserial()
{
if(s.size()==0)
return NULL;
if(s[j]=='!') {
j++;
if(j>=s.size())
return NULL;
}
if(s[j]=='#'){
j++;
return NULL;
}
int num=0;
while(s[j]>='0' && s[j]<='9'){
num=num*10+s[j++]-'0';}
TreeNode *root=new TreeNode(num);
root->left=Deserial();
root->right=Deserial();
return root;
}
};
面试题38
class Solution {
public:
vector<string> res;
void dfs(string s, int x){
if(x==s.size()-1){
res.push_back(s);
return;
}
set<int> st;//存x位置固定过的字符,下面的循环i每次换一个字符固定在这里
for(int i=x; i<s.size(); ++i){
if(st.find(s[i]) != st.end()) continue;//x位置已经固定过这个字符了
st.insert(s[i]);
swap(s[i], s[x]);
dfs(s, x+1);
swap(s[i], s[x]);
}
}
vector<string> permutation(string s) {
dfs(s,0);
return res;
}
};
面试题39
计数法做
class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> numbers) {
int cur=numbers[0];
int flag=1;
for(int i=1; i<numbers.size(); ++i){
if(numbers[i] == cur){
flag++;
}
else{
//注意这里不能直接flag--
if(flag==0){//为0的时候cur换成当前数字,频率改为1
cur=numbers[i];
flag=1;
}
else flag--;
}
}
return cur;
}
};
面试题40
题解链接
快排的划分部分,划分出来左边<=arr[l],右边>=arr[l],每次至少去掉一个arr[i]
class Solution {
public:
vector<int> quickSort(vector<int>& arr, int k, int l, int r){
int i=l, j=r;
while(i < j){
while(i<j && arr[j]>=arr[l]) j--;//这里注意先j后i的话,j最终指向<arr[l]的数,然后下面的i不能越过j,所以也指向<arr[l]的数,这里不能先i后j
while(i<j && arr[i]<=arr[l]) i++;
swap(arr[i], arr[j]);
}
swap(arr[i], arr[l]);//i放在正确位置
if(i>k) return quickSort(arr, k, l, i-1);
if(i<k) return quickSort(arr, k, i+1, r);//至少去掉arr[i]
vector<int> res;
res.assign(arr.begin(), arr.begin()+k);
return res;
}
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
if(k >= input.size()) return input;
return quickSort(input, k, 0, input.size()-1);
}
};
面试题41
堆
class Solution {
public:
priority_queue<int, vector<int>, less<int>> maxHeap;
priority_queue<int, vector<int>, greater<int>> minHeap;
void Insert(int num) {
if(maxHeap.size()==minHeap.size()){
maxHeap.push(num);
minHeap.push(maxHeap.top());
maxHeap.pop();
}
else{
minHeap.push(num);
maxHeap.push(minHeap.top());
minHeap.pop();
}
}
double GetMedian() {
if(maxHeap.size()==minHeap.size()){
return (1.0*maxHeap.top()+1.0*minHeap.top())/2;
}
else
return minHeap.top();
}
};
面试题42
动规,带上数组先写一遍,再优化掉空间复杂度
class Solution {
public:
int FindGreatestSumOfSubArray(vector<int> array) {
int n=array.size();
vector<int> s(n,0);
s[0]=array[0];
int ans=s[0];
for(int i=1; i<n; ++i){
s[i]=max(array[i], s[i-1]+array[i]);
//s[i]是带上a[i]的最大连续子数组和
ans=max(ans, s[i]);
}
return ans;
}
};
优化空间复杂度
class Solution {
public:
int FindGreatestSumOfSubArray(vector<int> array) {
int n=array.size();
//vector<int> s(n,0);
//s[0]=array[0];
int ans=array[0];
int si=array[0];
for(int i=1; i<n; ++i){
si=max(array[i], si+array[i]);
//s[i]是带上a[i]的最大连续子数组和
ans=max(ans, si);
}
return ans;
}
};
这题还有贪心解法。
面试题43
找规律,写公式
btw,这个min,max,画个分段函数图像就能看出来了。
官方题解
class Solution {
public:
int NumberOf1Between1AndN_Solution(int n) {
long long mulk=1;
int ans=0;
for(int k=0; n>=mulk; ++k){//这个k其实不用也行
ans+=((n/(mulk*10))*mulk+min(max(n%(mulk*10)-mulk+1, 0LL), mulk));
mulk*=10;
}
return ans;
}
};
面试题44
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param n int整型
* @return int整型
*/
int findNthDigit(int n) {
// write code here
if(n==0) return 0;
int digit=1;
int start=1;
long count=9;
while(n>count){
n=(int)(n-count);
digit++;
start=start*10;
count=(long)start*9*digit;
}
int num = start+(n-1)/digit;
int index=(n-1)%digit;
char ans=to_string(num)[index];
//int result=ans-'0';
return ans-'0';
}
};
class Solution {
public:
int findNthDigit(int n) {
if(n==0) return 0;
long start=1, digit=1;
long count=9;
while(n>count){
start*=10;
digit++;
n-=count;
count=9*digit*start;
}
int num=start+(n-1)/digit;
int index=(n-1)%digit;
char ans=to_string(num)[index];
return ans-'0';
}
};
面试题45
class Solution {
public:
vector<string> snumbers;
void quickSort(vector<string> &v, int l, int r){
if(l>=r) return;
int i=l,j=r;
while(i<j){
while(i<j && v[j]+v[l] >= v[l]+v[j]) j--;
//注意这里容易漏掉i<j &&
while(i<j && v[i]+v[l] < v[l]+v[i]) i++;
swap(v[i], v[j]);
}
swap(v[i], v[l]);
quickSort(v, l, i-1);
quickSort(v, i+1, r);
}
string PrintMinNumber(vector<int> numbers) {
if (numbers.size()==0) return "";
for(auto i:numbers) snumbers.push_back(to_string(i));
quickSort(snumbers, 0, numbers.size()-1);
string ans="";
for(auto s:snumbers){
ans+=s;
}
return ans;
}
};
面试题46
这题要在leetcode做,牛客版本不一样,加了对0的判断,但是用例没写清楚,10算1种,而110算2种,属于用例设计问题
就是个简单动规。
class Solution {
public:
int translateNum(int num) {
string snum=to_string(num);
int n=snum.size();
if(n<2) return n;
vector<int> v(n+1, 0);
v[0]=1;
v[1]=1;
for(int i=2; i<=n; ++i){
if(snum[i-2]=='1' || (snum[i-2]=='2' && snum[i-1]<='5')){
v[i]=v[i-2]+v[i-1];
}
else v[i]=v[i-1];
}
return v[n];
}
};
空间复杂度优化
class Solution {
public:
int translateNum(int num) {
string snum=to_string(num);
int n=snum.size();
if(n<2) return n;
//vector<int> v(n+1, 0);
int v0=1;
int v1=1;
for(int i=2; i<=n; ++i){
if(snum[i-2]=='1' || (snum[i-2]=='2' && snum[i-1]<='5')){
int temp=v1;
v1=v0+v1;
v0=temp;
}
else v0=v1;
}
return v1;
}
};
知识
- list
- char *怎么转换
- 堆,大根堆,小根堆,push,pop,top
priority_queue<int, vector<int>, less<int>> maxHeap;
priority_queue<int, vector<int>, greater<int>> minHeap;
- long long 0 写成
ans+=((n/(mulk*10))*mulk+min(max(n%(mulk*10)-mulk+1, 0LL), mulk));