【leetcode】3. 无重复字符的最长子串&&16. 最接近的三数之和&&104. 二叉树的最大深度(java实现)

  • 无重复字符的最长子串

给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例:

输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
     请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串

代码:

class Solution {
    public int lengthOfLongestSubstring(String s) {
        
        if(s.length() == 0){
            return 0;
        }
        
        //用于计数
        int count = 0;
        int max = -1;
        
        //将字符串储存成字符数组
        char[] strs = s.toCharArray();
        //定义一个集合存储不重复的字符
        List<Character> str_list = new ArrayList<>();
        
        //跟python的for i in list是一个用法
        for(char c: strs){
            //当遇上重复的字符时
            if(str_list.contains(c)){
                //如果之前的计数大于max,则对max重新赋值
                if(count > max){
                    max = count;
                }
                //遇上重复字符,就要对集合里面的字符进行清空,与从同时每删一个计数减一
                while(str_list.contains(c)){
                    count--;
                    System.out.println(str_list.get(0));
                    str_list.remove(0);
                    System.out.println("---");
                }
            }
            str_list.add(c);
            count++;
        }
        
        if(count >= max){
            max = count;
        }
        return max;
                       
    }
}

  • 最接近的三数之和

对于这道题采用的是一层循环+双指针的方式解题

class Solution {
    public int threeSumClosest(int[] nums, int target) {
        
        int i, j, k;
        //定义最接近target的数
        int closet=nums[0] + nums[1] + nums[2];
        
        //对传进来的数组进行排序
        Arrays.sort(nums);
        for(i=0; i<nums.length-2; i++){
            
                j = i + 1;
                k = nums.length - 1;
            
            //双指针,一个指向头,一个指向尾
            while(k > j){

                int num = nums[j] + nums[i] + nums[k];
                
                //当前三数与target的差的绝对值比上一次的差小的话,对最接近的数重新赋值
                if(Math.abs(num - target) < Math.abs(closet-target)){
                    closet = num;
                }
                
                //因为nums是有序数组,通过判断num与target的关系来确定两个指针的走向
                if(num > target){
                    k--;
                }else if(num < target){
                    j++;
                           
                }else{
                    //num与target相等即返回target
                    return target;
                }
                 
            }
        }
        return closet;
        
    }
}

  • 二叉树的最大深度

用递归解,终止条件是节点为空,返回给上一级的是当前节点的个数,为空返回0,不为空返回1,因此这里需要用 maxDepth(root.left)+1 来返回给上一级。

class Solution {
    public int maxDepth(TreeNode root) {
        if(root == null){
            return 0;
        }
        return Math.max(maxDepth(root.left)+1,maxDepth(root.right)+1);
    }
}

在评论区找到了另一种解法 栈解法

栈解法:深度优先搜索,栈的最大长度就是树的最大深度

var maxDepth = function(root) {
    if(root === null) return 0;
    let depth = 1;
    let stack = [root];
    let currentNode = root;
    
    while(stack.length) {
        while(getNotArrivedChild(currentNode)) {
            stack.push(getNotArrivedChild(currentNode));
            currentNode = getNotArrivedChild(currentNode);
            //这里给访问过的节点标记一下
            currentNode.ok = true;
            //如果加入这个节点后,stack长度大于当前depth,就更新depth为stack长度。
            if(stack.length > depth) depth = stack.length;
        }
        stack.pop();
        currentNode = stack[stack.length-1];
    }
    
    return depth;
};

//这个函数用来返回当前节点还未被访问过的子节点
function getNotArrivedChild(root) {
    if(root.left && !root.left.ok) return root.left;
    if(root.right && !root.right.ok) return root.right;
    return null;
}

再记录一下栈解法用c实现的,方便复习:

#define N (100)
// 记录每个节点和对应的高度
struct stack{
    struct TreeNode* node;
    int depth;
}stack[N];
// 桟指针和树最大高度
int i = 0;
int depth = 0;

int maxDepth(struct TreeNode* root) {
    if(root == NULL) return 0;
    
    stack[i].node = root;
    stack[i].depth = depth = 1;
    i++;
    
    while(i>0)  // 桟不空
    {
        // 出栈
        --i;
        // 保存出栈的节点和高度
        struct TreeNode* t = stack[i].node;
        int curDepth = stack[i].depth;
        // 更新最大高度
        depth = depth > curDepth ? depth : curDepth;
        
        if(t->left != NULL) // 不为空则入栈
        {
            stack[i].node = t->left;
            stack[i].depth = curDepth + 1;
            ++i;
        }
        
         if(t->right != NULL) // 不为空则入栈
        {
            stack[i].node = t->right;
            stack[i].depth = curDepth + 1;
            ++i;
        }
    }
    
    return depth;
        
}

猜你喜欢

转载自blog.csdn.net/qq_43538596/article/details/89222448