Java常见算法(三)【二叉树的最小深度计算的深度优先和广度优先、贪心算法常见实例】

一、二叉树的最小深度

https://www.bilibili.com/video/BV1Jv411A7Ty?p=17
https://www.bilibili.com/video/BV1Jv411A7Ty?p=18

1、深度优先:先找到所有叶子节点

在这里插入图片描述

 //1、深度优先算法:先找到所有叶子节点
    public static int minDepth(TreeNode root){
    
    
        if(root==null){
    
    
            return 0;
        }
        if(root.left==null && root.right==null){
    
    
            return 1;
        }
        int min=Integer.MAX_VALUE;
        //先递归遍历左节点
        if(root.left!=null){
    
    
            min=Math.min(minDepth(root.left),min);
        }
        //再递归遍历右节点
        if(root.right!=null){
    
    
            min=Math.min(minDepth(root.right),min);
        }
        return min+1;
    }

2、广度优先:从根节点开始找字节点

在这里插入图片描述

//2、广度优先:使用一个先进先出的队列,遍历完当前节点后遍历他子节点的同一层节点
    public static int minDepth1(TreeNode root){
    
    
        if(root==null){
    
    
            return 0;
        }
        //创建一个队列
        Queue queue = new LinkedList<>();
        root.deep=1;
        queue.offer(root);
        while (!queue.isEmpty()){
    
    
            //取出一个节点,并判断他是否为叶子节点
            TreeNode node= (TreeNode) queue.poll();
            if(node.left==null && node.right==null){
    
    
                return node.deep;
            }
            if(node.left!=null){
    
    
                node.left.deep=node.deep+1;
                queue.offer(node.left);
            }
            if(node.right!=null){
    
    
                node.right.deep=node.deep+1;
                queue.offer(node.right);
            }
        }
        return 0;
    }

实验源码:

package com.example.rabbitmq;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.LinkedList;
import java.util.Queue;

@SpringBootTest
/*
    二叉树的最小深度
    1、深度优先:先找到所有叶子节点
    2、广度优先:
 */
class SuanfaApplicationTests13 {
    
    

    //定义一个二叉树
    static class TreeNode{
    
    
        int val;
        TreeNode left;
        TreeNode right;
        int deep;//深度
        TreeNode(int val,TreeNode left,TreeNode right){
    
    
            this.val=val;
            this.left=left;
            this.right=right;
        }
    }

    //1、深度优先算法:先找到所有叶子节点
    public static int minDepth(TreeNode root){
    
    
        if(root==null){
    
    
            return 0;
        }
        if(root.left==null && root.right==null){
    
    
            return 1;
        }
        int min=Integer.MAX_VALUE;
        //先递归遍历左节点
        if(root.left!=null){
    
    
            min=Math.min(minDepth(root.left),min);
        }
        //再递归遍历右节点
        if(root.right!=null){
    
    
            min=Math.min(minDepth(root.right),min);
        }
        return min+1;
    }

    //2、广度优先:使用一个先进先出的队列,遍历完当前节点后遍历他子节点的同一层节点
    public static int minDepth1(TreeNode root){
    
    
        if(root==null){
    
    
            return 0;
        }
        //创建一个队列
        Queue queue = new LinkedList<>();
        root.deep=1;
        queue.offer(root);
        while (!queue.isEmpty()){
    
    
            //取出一个节点,并判断他是否为叶子节点
            TreeNode node= (TreeNode) queue.poll();
            if(node.left==null && node.right==null){
    
    
                return node.deep;
            }
            if(node.left!=null){
    
    
                node.left.deep=node.deep+1;
                queue.offer(node.left);
            }
            if(node.right!=null){
    
    
                node.right.deep=node.deep+1;
                queue.offer(node.right);
            }
        }
        return 0;
    }

    @Test
    public void sf0(){
    
    
        //构造一个二叉树
        TreeNode node7=new TreeNode(7,null,null);
        TreeNode node6=new TreeNode(6,node7,null);
        TreeNode node5=new TreeNode(5,null,null);
        TreeNode node4=new TreeNode(4,null,null);
        TreeNode node3=new TreeNode(3,node6,null);
        TreeNode node2=new TreeNode(2,node4,node5);
        TreeNode node1=new TreeNode(1,node2,node3);

        System.out.println(minDepth(node1));
        System.out.println(minDepth1(node1));

    }

}

结果:

3
3

二、计算数组中最长连续递增序列(贪心算法经典实例)

https://www.bilibili.com/video/BV1Jv411A7Ty?p=19

给定一个未经过排序的整数数组,找到最长且连续递增的子序列,并返回该序列的长度。
注:序列的下标是连续的。

贪心算法

public static int findLength(int[] nums){
    
    
        int start=0;
        int max=0;
        for (int i = 1; i <nums.length ; i++) {
    
    
            if(nums[i]<=nums[i-1]){
    
    
                start=i;
            }
            max=Math.max(max,i-start+1);
        }
        return max;
    }

实验源码:

package com.example.rabbitmq;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.LinkedList;
import java.util.Queue;

@SpringBootTest
/*
    最长连续递增序列
    给定一个未经过排序的整数数组,找到最长且连续递增的子序列,并返回该序列的长度。
    序列的下标是连续的。
 */
class SuanfaApplicationTests14 {
    
    

    //1、贪心算法
    public static int findLength(int[] nums){
    
    
        int start=0;
        int max=0;
        for (int i = 1; i <nums.length ; i++) {
    
    
            if(nums[i]<=nums[i-1]){
    
    
                start=i;
            }
            max=Math.max(max,i-start+1);
        }
        return max;
    }

    @Test
    public void sf0(){
    
    
        int[] arr=new int[]{
    
    1,2,3,2,3,4,3,4,5,6,7};
        System.out.println(findLength(arr));

    }

}

结果:

5

三、柠檬水找零(贪心算法经典实例)

https://www.bilibili.com/video/BV1Jv411A7Ty?p=20
在这里插入图片描述

贪心算法

 //贪心算法
    public static boolean findLength(int[] nums){
    
    
        int five=0;//5元的个数
        int ten=0;//10元的个数
        for (int num : nums) {
    
    
            //1、收到的是5块钱,不需要找钱
            if(num==5){
    
    
                five++;
                //2、收到的是10块钱
            }else if(num==10){
    
    
                if(five>0){
    
    
                    five--;
                    ten++;
                }else {
    
    
                    return false;
                }
                //3、收到的是二十块
            }else{
    
    
                if(five>0 && ten>0){
    
    
                    five--;
                    ten--;
                }else if(five>=3){
    
    
                    five=five-3;
                }else{
    
    
                    return false;
                }
            }
        }
        return true;
    }

实验源码:

package com.example.rabbitmq;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.Arrays;

@SpringBootTest
/*
    柠檬水找零钱(贪心算法经典实例)
    关键:5+5=10    5+10=15   5+5+5=15   ,所以遇到20块找零钱的时候,
    最优的是找他 10+5,没有的情况下再考虑 5+5+5
 */
class SuanfaApplicationTests15 {
    
    

    //贪心算法
    public static boolean findLength(int[] nums){
    
    
        int five=0;//5元的个数
        int ten=0;//10元的个数
        for (int num : nums) {
    
    
            //1、收到的是5块钱,不需要找钱
            if(num==5){
    
    
                five++;
                //2、收到的是10块钱
            }else if(num==10){
    
    
                if(five>0){
    
    
                    five--;
                    ten++;
                }else {
    
    
                    return false;
                }
                //3、收到的是二十块
            }else{
    
    
                if(five>0 && ten>0){
    
    
                    five--;
                    ten--;
                }else if(five>=3){
    
    
                    five=five-3;
                }else{
    
    
                    return false;
                }
            }
        }
        return true;
    }
    
    @Test
    public void sf0(){
    
    
        //不能找开的情况
        int[] arr=new int[]{
    
    5,10,20};
        //能找开的情况
        int[] arr1=new int[]{
    
    5,5,10,20};
        System.out.println(Arrays.toString(arr)+",不能找开的情况:"+findLength(arr));
        System.out.println(Arrays.toString(arr1)+"能找开的情况:"+findLength(arr1));
    }
}

结果:

[5, 10, 20],不能找开的情况:false
[5, 5, 10, 20]能找开的情况:true

四、三角形的最大周长(贪心算法经典实例)

https://www.bilibili.com/video/BV1Jv411A7Ty?p=21
在这里插入图片描述

贪心算法

    //贪心算法
    public static int findMaxLen(int[] nums){
    
    
        //先进行排序,然后从后往前找三个最大的进行尝试,看看是否满足三角形三遍的条件:两边之和大于第三边。
        Arrays.sort(nums);
        for (int i = nums.length-1; i >=2 ; i--) {
    
    
            if(nums[i-2]+nums[i-1]>nums[i]){
    
    
                return nums[i-2]+nums[i-1]+nums[i];
            }
        }
        return 0;
    }

实验源码:

package com.example.rabbitmq;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.Arrays;

@SpringBootTest
/*
     三角形的最大周长(贪心算法经典实例)
 */
class SuanfaApplicationTests16 {
    
    

    //贪心算法
    public static int findMaxLen(int[] nums){
    
    
        //先进行排序,然后从后往前找三个最大的进行尝试,看看是否满足三角形三遍的条件:两边之和大于第三边。
        Arrays.sort(nums);
        for (int i = nums.length-1; i >=2 ; i--) {
    
    
            if(nums[i-2]+nums[i-1]>nums[i]){
    
    
                return nums[i-2]+nums[i-1]+nums[i];
            }
        }
        return 0;
    }

    @Test
    public void sf0(){
    
    
        int[] arr=new int[]{
    
    5,10,3,20};
        int[] arr1=new int[]{
    
    5,10,6,20};
        System.out.println(Arrays.toString(arr)+"不能组成三角形,周长为:"+findMaxLen(arr));
        System.out.println(Arrays.toString(arr1)+"能组成三角形,周长为:"+findMaxLen(arr1));
    }
}

实验结果:

[5, 10, 3, 20]不能组成三角形,周长为:0
[5, 10, 6, 20]能组成三角形,周长为:21

猜你喜欢

转载自blog.csdn.net/YL3126/article/details/121369827