《剑指offer》JZ21 ~ JZ30

Posted 黑桃️

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《剑指offer》JZ21 ~ JZ30相关的知识,希望对你有一定的参考价值。


JZ21 栈的压入、弹出序列

class Solution {
public:
    bool IsPopOrder(vector<int> pushV,vector<int> popV) {
        stack<int> s;
        int l=0;
        for(int i=0;i<pushV.size();i++)
        {
        	// 不相等,先入栈
            if(pushV[i] != popV[l])  s.push(pushV[i]);
            else 
            {
                l++;
                // 看看栈顶是否有和popV相等的,有则出栈
                while(s.size() && s.top()==popV[l]) 
                {
                    l++;
                    s.pop();
                }
            }
        }
        // 遍历完了栈中还有元素,表示失败
        if(s.size()) return false;
        else return true;
    }
};

JZ22 从上往下打印二叉树


典型的层序遍历

/*
struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
	TreeNode(int x) :
			val(x), left(NULL), right(NULL) {
	}
};*/
class Solution {
public:
    vector<int> PrintFromTopToBottom(TreeNode* root) {
        vector<int> ans;
        queue<TreeNode*> q;
        if(root == NULL) return ans;
        q.push(root);
        while(!q.empty())
        {
            TreeNode* t = q.front();
            q.pop();
            ans.push_back(t->val);
            if(t->left) q.push(t->left);
            if(t->right) q.push(t->right);
        }
        return ans;
    }
};

JZ23 二叉搜索树的后序遍历序列


结合二叉搜索树和二叉树后序遍历的特点
二叉搜索树:左子树都比根小,右子树都比根大,且左右子树都为二叉搜索树
后序遍历:左右根的顺序,最后一个为根

class Solution {
public:
    bool VerifySquenceOfBST(vector<int> sequence) {
        if(!sequence.size()) return false;
        return dfs(sequence);
    }
    
    bool dfs(vector<int> sequence)
    {
        if(sequence.size()<=1) return true;
        // 分离左右子树,然后各自遍历
        vector<int> l,r;
        int i=0,len = sequence.size();
        // 小于根(最后一个),放入左子树数组
        while(i<len-1 && sequence[i]<sequence.back()) 
            l.push_back(sequence[i++]);
        
        // 大于跟,放入右子树数组
        while(i<len-1 && sequence[i]>sequence.back())
            r.push_back(sequence[i++]);
        
        // 左右子树放完后,发现还没遍历到根,那么代表存在不符合条件的
        if(i<len-1) return false;
        return dfs(l) && dfs(r);
    }
};

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


回溯,题中路径指的是 根到叶子

class Solution {
public:
    vector<vector<int>> ans;
    vector<int> t;
    
    vector<vector<int> > FindPath(TreeNode* root,int expectNumber) {
        if(root==NULL) return ans;
        t.push_back(root->val);
        dfs(root, root->val, expectNumber);
        return ans;
    }
    
    void dfs(TreeNode* root, int now, int expectNumber)
    {
        if(now > expectNumber) return;
        // 叶子,路径和也满足要求
        if(root->left==NULL && root->right==NULL && now==expectNumber)
        {
            ans.push_back(t);
            return;
        }
        // 走左
        if(root->left) 
        {
            t.push_back(root->left->val);
            dfs(root->left, now+root->left->val, expectNumber);
            t.pop_back();
        }
        // 走右
        if(root->right) 
        {
            t.push_back(root->right->val);
            dfs(root->right, now+root->right->val, expectNumber);
            t.pop_back();
        }
    }
};

JZ25 复杂链表的复制

没怎么看明白想表达什么。。。先跳过


JZ26 二叉搜索树与双向链表



通过中序遍历把结果放入数组中,然后重新拼接


class Solution {
public:
    vector<TreeNode*> node;
    TreeNode* Convert(TreeNode* pRootOfTree) {
        if(pRootOfTree==NULL) return NULL;
        TreeNode* head = new TreeNode(-1);
        TreeNode* p = head;
        TreeNode* q;
        mid(pRootOfTree);
        for(int i=0;i<node.size();i++)
        {
            q = new TreeNode(node[i]->val);
            p->right = q;
            if(p!=head) q->left = p;
            p = p->right;
        }
        return head->right;
    }
    // 中序遍历放入数组中
    void mid(TreeNode* pRootOfTree)
    {
        if(pRootOfTree->left) mid(pRootOfTree->left);
        node.push_back(pRootOfTree);
        if(pRootOfTree->right) mid(pRootOfTree->right);
    }
    
};

JZ27 字符串的排列


全排列,回溯,也可以直接用next_permutation

class Solution {
public:
    vector<string> ans;
    string t;
    bool vis[10]={false};
    
    vector<string> Permutation(string str) {
        if(str.length()==0) return ans;
        dfs(str);
        return ans;
    }
    
    
    void dfs(string str)
    {
    	// 获得一种情况
        if(t.length() == str.length())
        {
        	// 判断是否有相同的
            for(string x:ans)
                if(x==t) return;
            ans.push_back(t);
            return;
        }
        
        for(int i=0;i<str.length();i++)
        {
        	// 回溯
            if(vis[i]==false)
            {
                vis[i]=true;
                t+=str[i];
                dfs(str);
                t.erase(t.length()-1);
                vis[i]=false;
            }
        }
    }
};

JZ28 数组中出现次数超过一半的数字

class Solution {
public:
    int MoreThanHalfNum_Solution(vector<int> numbers) {
        map<int,int> m;
        for(int i=0;i<numbers.size();i++)
            if(++m[numbers[i]]*2 > numbers.size()) 
                return numbers[i];
        return -1;
    }
};

JZ29 最小的K个数


用优先队列实现小顶堆

class Solution {
public:
    vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
        vector<int> ans;
        priority_queue<int,vector<int>,greater<> > q;
        for(int x:input) q.push(x);
        while(k--)
        {
            ans.push_back(q.top());
            q.pop();
        }
        return ans;
    }
};

JZ30 连续子数组的最大和


梦开始的dp不是这个就是那啥数字金字塔
max(放弃前面所有而使用当前值,前面所有+当前值)

class Solution {
public:
    int FindGreatestSumOfSubArray(vector<int> array) {
        int dp[100]={array[0]},ans=dp[0];
        for(int i=1;i<array.size();i++)
        {
            dp[i] = max(array[i],dp[i-1]+array[i]);
            ans = max(ans, dp[i]);
        }
        return ans;
    }
};

以上是关于《剑指offer》JZ21 ~ JZ30的主要内容,如果未能解决你的问题,请参考以下文章

《剑指offer》JZ21 ~ JZ30

《剑指offer》JZ21 ~ JZ30

《剑指offer》JZ41 ~ JZ50

《剑指offer》JZ1 ~ JZ10

《剑指offer》JZ1 ~ JZ10

《剑指offer》JZ11 ~ JZ20