2022-03-14剑指37-46

面试题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));
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值