剑指 Offer 58 - II左旋转字符串 && 剑指 Offer 55 - I二叉树的深度

力扣剑指offer刷题博客第一篇,后续会更完所有题目,题库链接https://leetcode-cn.com/problemset/lcof/

每道题力求多种解法!!!

目录

左旋转字符串

剑指 Offer 55 - I. 二叉树的深度


左旋转字符串

1.暴力做法

class Solution {
public:
    string reverseLeftWords(string s, int n) {
        int len=s.length();
        string ans="";
        for(int i=n;i<len;++i){
            ans+=s[i];
        }
        for(int i=0;i<n;++i){
             ans+=s[i];
        }
        return ans;
    }
};

执行用时:8 ms, 内存消耗:7.5 MB

2.STL版

class Solution {
public:
    string reverseLeftWords(string s, int n) {
        int len=s.length();
        string ans=s.substr(n,len-n);//substr(a,b):a表示起始位置,b表示从起始位置开始算的字符数
        for(int i=0;i<n;++i){
            ans+=s[i];
        }
        return ans;
    }
};

注:substr(a,b):a表示起始位置,b表示从起始位置开始算的字符数 ,即获取从位置a开始长度为b的字符串(字符串初始位置为0)

执行用时:4 ms, 在所有 C++ 提交中击败了84.52%的用户

内存消耗:7.5 MB, 在所有 C++ 提交中击败了64.48%的用户

3.三次反转字符串的骚操作(题解区学来的)

思路:

(1)重写reverse函数,因为我们要实现特定位置的反转,原来的函数不足以支持这项操作,原本是reverse(s.begin(),s,end()),s.begin()表示的是取s的首元素地址

(2)将原字符串s分为两个子串,要转移到尾部的是s1,另一个为s2,设s="abcde",k=2,结果为s="cdeab"

s1=ab,s2=cde

i.先将s2整体反转,s2=edc

ii.反转s,s=cdeba,此时s1(别忘了这表示要移到尾部的字符串)已经在尾部了,但是顺序不对,所以要再反转s1

iii.反转s1得到最终结果s=cdeab

class Solution {
public:
    string reverse(string &s,int i,int j){
        
        while(i<j){
            char temp=s[i];
            s[i++]=s[j];
            s[j--]=temp;
        }
        return s;
    }
    string reverseLeftWords(string s, int n) {
        int len=s.length();
        reverse(s,n,len-1);
        reverse(s,0,len-1);
        reverse(s,len-n,len-1);
        return s;
    }
};

剑指 Offer 55 - I. 二叉树的深度

1.后序遍历二叉树(DFS--深度优先搜索)

后序遍历:左(左子树)右(子树)中(父节点)

注:最后return+1表示浏览当前节点即父(相对于左右子树来说的)节点

深度优先搜索:一条路走到黑,前面没有路了再往后退到离得最近的分岔口走另一条还没走过的路,常用递归或栈实现

找出左右子树的深度,最后取两者之中的最大值+1就是结果

/**
 * 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 NULL;//空指针要返回  不然会报错
        int t1=maxDepth(root->left);
        int t2=maxDepth(root->right);
        return max(t1,t2)+1;
    }
};

执行用时:4 ms, 在所有 C++ 提交中击败了98.98%的用户

内存消耗:18.4 MB, 在所有 C++ 提交中击败了85.66%的用户

之前做错的代码和错误样例,错误原因是重复计算了深度,低级错误!!!

2.层次遍历(BFS--广度优先搜索)

层次遍历:遍历过程如其名字,先遍历完上一层所有元素再遍历下一层元素,队列结合while实现

思路:

val作用是用来标记当前层数,每次弹出队首元素时与结果变量对比一次取最大值;

每次浏览当前节点

/**
 * 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;//空树直接返回0
        queue<TreeNode*>q;
        root->val=1;
        q.push(root);//入队
        int ans=0;
        while(!q.empty()){
            TreeNode* temp=q.front();//取队首元素
            ans=max(temp->val,ans);
            q.pop();//出队
            if(temp->left){
                temp->left->val=temp->val+1;
                q.push(temp->left);
            }
            if(temp->right){
                temp->right->val=temp->val+1;
                q.push(temp->right);
            }
        }
        return ans;
    }
};

执行用时:8 ms, 在所有 C++ 提交中击败了92.63%的用户

内存消耗:18.6 MB, 在所有 C++ 提交中击败了79.93%的用户

3.层次遍历的另一个版本

双重while,虽然用时和内存不太行,思路还是值得借鉴

/**
 * 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;
        queue<TreeNode*>q;
        q.push(root);//入队
        int ans=0;
        while(!q.empty()){
            
            
            queue<TreeNode*>p;
            while(!q.empty()){ //刚开始进入第二重while时,q内遗留的是当前层的所有节点
                TreeNode* temp=q.front();//取队首元素
                if(temp->left){
                    p.push(temp->left);
                }
                if(temp->right){ 
                    p.push(temp->right);
                }
                q.pop();
            }
            //退出第二重while循环后p内存的是下一层所有节点
            ans++;
            q=p;//当前层遍历完毕进入下一层
        }
        return ans;
    }
};

执行用时:16 ms, 在所有 C++ 提交中击败了46.09%的用户

内存消耗:20.4 MB, 在所有 C++ 提交中击败了5.17%的用户

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值