练习备战(三)

一、栈的压入、弹出序列

非常精明的写法。 当入栈元素和出栈序列的元素相同时,
我们就一直出栈,最终判断栈是否为空,
栈为空, 则该出栈序列正确
不为空, 出栈序列不正确。

class Solution {
public:
    bool IsPopOrder(vector<int> pushV,vector<int> popV) {
        if(pushV.size() == 0 || popV.size() == 0 ||
                pushV.size() != popV.size() )
        {
            return false;
        }
         
        stack<int> st;
         
        int j = 0;
        for(int i = 0; i < pushV.size(); i++) {
            st.push(pushV[i]);    //入栈
            while(!st.empty() && popV[j] == st.top()) {
                st.pop();    //出栈
                j++;
            }
        }
         
        return st.empty();
    }
};

二、把二叉树打印成多行

层序遍历的写法。

class Solution {
public:
        vector<vector<int> > Print(TreeNode* pRoot) {
            vector<vector<int>> vec;
            if(!pRoot) {
                return vec;
            }
             
            queue<TreeNode*> qe;
            qe.push(pRoot);
             
            while(!qe.empty()) {
                 
                vector<int> tmp;
                int size = qe.size();               
                for(int i = 0; i < size; i++) {
                    TreeNode* node = qe.front();
                    qe.pop();
                    tmp.push_back(node->val);
                    if(node->left) {
                        qe.push(node->left);
                    }
                    if(node->right) {
                        qe.push(node->right);
                    }
                }
                vec.push_back(tmp);
            }
             
            return vec;
        }
     
};

三、二叉搜索树的后序遍历序列

这道题是给出二叉搜索树的后序序列, 判断后序序列是否正确的问题。
需要利用到二叉搜索树的性质。

class Solution {
public:
     
    bool IsRight(vector<int> sequence, int begin, int end) {
        if(begin >= end) {
            return true;
        }
         
        int root = sequence[end];    //拿到根节点
        int i = 0;
        for(; i < end; i++) {
            if(sequence[i] >= root) {
                break;
            }
        }
        //还需要判断[i~end) 之间序列是否大于root, 如果大于才正确。
        for(int j = i; j <= end; j++) {
            if(sequence[j] < root) {
                return false;
            }
        }
         
        return IsRight(sequence, begin, i - 1) &&
            IsRight(sequence, i, end - 1);
    }
     
    bool VerifySquenceOfBST(vector<int> sequence) {
        if(sequence.size() == 0) {
            return false;
        }
         
        return IsRight(sequence, 0, sequence.size() - 1);
    }
};

四、二叉树中和为某一值的路径

判断一条路径上所有值相加起来是否为key值。
典型的回溯思想

class Solution {
public:
     
    void IsJudge(TreeNode* root, int key, vector<vector<int>>& vec, vector<int>& tmp) {
        if(!root) {
            return;
        }
         
        tmp.push_back(root->val);        //把当前的元素存储起来
        IsJudge(root->left, key, vec, tmp);
        IsJudge(root->right, key, vec, tmp);
        if(root->left == nullptr && root->right == nullptr) {
            //代表root结点为叶子节点
            int sum = 0;
            for(const auto& vit : tmp) {
                sum += vit;
            }
            if(sum == key ){
                //证明这条路径是成功的。
                vec.push_back(tmp);    //保存了这条路径
            }
        }
        //相当于一个结点左右子树判断完毕。 这个结点走完了, 出容器吧
        tmp.pop_back();
    }
     
    vector<vector<int> > FindPath(TreeNode* root,int expectNumber) {
         
        vector<vector<int>> vec;
        if(!root) {
            return vec;
        }
         
        vector<int> tmp;
        IsJudge(root, expectNumber, vec, tmp);
        return vec;
    }
};

五、字符串的排列

DFS算法思想。

class Solution {
public:
     
    bool IsCopy(const vector<string>& vec, const string& str) {
        for(const auto& vit : vec) {
            if(vit == str) {
                return true;
            }
        }
        return false;
    }
 
    void PermutationHeap(string& str, int begin, vector<string>& vec) {
        if(begin == str.size() - 1) {
            //找到了一串数据。
            if(!IsCopy(vec, str)){	   //不为重复序列,则存进去
                vec.push_back(str);    //存进去
            } 
            return;
        }
         
        for(int i = begin; i < str.size(); i++) {
            swap(str[begin], str[i]);    //a,b,c随机的开头
            PermutationHeap(str, begin + 1, vec);
            swap(str[begin], str[i]);
        }
    }
     
    vector<string> Permutation(string str) {
        vector<string> vec;
        if(str.size() > 0) {
            PermutationHeap(str, 0, vec);
            sort(vec.begin(), vec.end());
        }
        return vec;
    }
};

六、最小的K个数

class Solution {
public:
    
    struct cmp {
        bool operator()(int a, int b) {
            return a < b;
        }
    };
    
    vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
        
        vector<int> vec;
        if(input.size() == 0 || k <= 0 || k > input.size()) {
            return vec;
        }
        
        priority_queue<int, vector<int>, cmp> pq;    //构建大根堆
        for(int i = 0; i < input.size(); i++) {
            if(i < k) {
                pq.push(input[i]);
            }
            else {
                if(input[i] < pq.top()) {
                    pq.pop();
                    pq.push(input[i]);
                }        
            }
        }
        
        for(int i = 0; i < k; i++) {
            vec.push_back(pq.top());
            pq.pop();
        }
        return vec;
    }
};
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值