【模拟面试】#18 N叉树的最大深度 最长特殊序列 II 接雨水

题目1

给定一个 N 叉树,找到其最大深度。

最大深度是指从根节点到最远叶子节点的最长路径上的节点总数。

例如,给定一个 3叉树 :

 

 

我们应返回其最大深度,3。

说明:

  1. 树的深度不会超过 1000
  2. 树的节点总不会超过 5000

思路及代码

遍历,注意是N叉树不是二叉树就行,记录最大层数

/*
// Definition for a Node.
class Node {
public:
    int val;
    vector<Node*> children;

    Node() {}

    Node(int _val) {
        val = _val;
    }

    Node(int _val, vector<Node*> _children) {
        val = _val;
        children = _children;
    }
};
*/

class Solution {
public:

    int maxDepth(Node* root) {
        int depth = 1;
        
        if(root == NULL) 
            return 0;
        else{
            int max = 0;
        for(int i = 0;i < root->children.size() ; i++){
            int n = 1 + maxDepth(root->children[i]);
             max = (max < n)?n:max;
        }
        depth = (depth >max)?depth:max;
        return depth;
        }
    }

    
};

题目2

给定字符串列表,你需要从它们中找出最长的特殊序列。最长特殊序列定义如下:该序列为某字符串独有的最长子序列(即不能是其他字符串的子序列)。

子序列可以通过删去字符串中的某些字符实现,但不能改变剩余字符的相对顺序。空序列为所有字符串的子序列,任何字符串为其自身的子序列。

输入将是一个字符串列表,输出是最长特殊序列的长度。如果最长特殊序列不存在,返回 -1 。

示例:

输入: "aba", "cdc", "eae"
输出: 3

提示:

  1. 所有给定的字符串长度不会超过 10 。
  2. 给定字符串列表的长度将在 [2, 50 ] 之间。

思路及代码

我们先根据字符串的长度进行排序,按照长度降序的方式进行。显然,如果当前字符串是特殊序列,那么就是最长的。对于一个字符串,我们判断它是不是特殊序列时,只需要判断它是不是长度比它长和相等的字符串的子序列。因此,我们需要用一个哈希表记录,当前长度比它长的不是特殊序列的字符串。

来源:https://blog.csdn.net/weixin_43750513/article/details/107365725

bool sortS (string& s1,string& s2){
    return s1.length() > s2.length();
}
class Solution {
private:
    unordered_map<int,set<string>> list;
public:
    bool isMax(string& str){		//判断字符串是否为特殊序列
        for(auto words : list){		//检查其是否为长度比它长的字符串的子序列
            if(words.first == str.length())  continue;
            for(auto word : words.second){
                int i=0,j=0;
                while(i<str.length() && j<word.length()){
                    if(str[i] == word[j]){
                        i++;
                        j++;
                    }else   j++;
                }
                if(i == str.length())   return false;		//是子序列,那么它就不是特殊序列
            }
        }
        return true;
    }
    bool addList(vector<string>& strs,unordered_map<string,int>& time,int l,int r){
        for(int i=l; i<r; i++){
            if(time[strs[i]] != 1){			//一个字符串出现1次以上,一定不是特殊序列
                if(isMax(strs[i]))			//如果它只出现一次时,他如果是特殊序列,我们就放到list中,用于检查其余字符串是否为其子序列
                    list[strs[i].length()].insert(strs[i]);
            }else if(isMax(strs[i]))  return true;		//出现1次,为特殊序列
        }
        return false;
    }
    int findLUSlength(vector<string>& strs) {
        sort(strs.begin(),strs.end(),sortS);		//根据长度进行排序
        int n = strs.size(),i=0,j;
        unordered_map<string,int> time;				//用于获取一个当前长度的字符串出现的次数
        while(i < n){
            time.clear();
            time[strs[i]]++;
            for(j=i+1; j<n; j++){
                if(strs[j].length() != strs[i].length())  break;
                time[strs[j]]++;
            }
            if(addList(strs,time,i,j))  return strs[i].length();		//检查当前长度是否存在特殊序列
            i = j;
        }
        return -1;
    }
};

题目3

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。

上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。 感谢 Marcos 贡献此图。

示例:

输入: [0,1,0,2,1,0,1,3,2,1,2,1]
输出: 6

思路及代码

左边最高和右边最高求一个最小值减去当前高度,就等于当前能装的水的量

来源:https://blog.csdn.net/cysisu/article/details/105556710

class Solution {
public:
    int getMaxRight(vector<int>& height, int index) {
		int maxRight = 0;
		for (; index < height.size(); index++) {
			if (height[index] > maxRight)
				maxRight = height[index];
		}
		return maxRight;
	}
	int trap(vector<int>& height) {
		int res = 0;
		int rightMax = getMaxRight(height, 1), leftMax = 0;
		for (int i = 0; i < height.size(); i++)
			if (rightMax < height[i])
				rightMax = height[i];
		for (int i = 0; i < height.size(); i++)
		{
			if (height[i] > leftMax)
				leftMax = height[i];
			if (height[i] == rightMax)
				rightMax = getMaxRight(height, i + 1);
			int diff = min(leftMax, rightMax) - height[i];
			res += (diff > 0 ? diff : 0);
		}
		return res;
	}
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值