算法合集(四)

今天事情比较多,主要来复习一下树型数据结构及贪心算法。

二叉树最小深度

给定一个二叉树,找出其最小深度。

深度优先

思路

(1)如果是叶子节点的话,我们可以将其深度设置为1;
(2)如果不是叶子节点,对比其左右子节点的深度以及之前遍历时保存的最小的深度,选其中最小,最终输出min+1即为本题的解。

package test;

public class TreeDeep {
	 static class TreeNode{
		 int val;
		 TreeNode left;
		 TreeNode right;
		 TreeNode(int val, TreeNode left, TreeNode right){
			 this.val = val;
			 this.left = left;
			 this.right = right;
		 }
	 }
	 
	 public static void main(String[] args) {
		 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));
	}
	 
	 //深度优先
	 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;
	 }
	 
}

广度优先

思路

(1)先将root的深度值设置为1。之后使用队列,将root放入队列中;
(2)如果左右节点为空,则说明找到最小深度所处的节点了,直接返回deep值;
(3)如果左节点不为空,则首先将左节点的深度在父节点深度的基础上加1,再将其放入队列中;
(4)如果右节点不空,同理。

package test;

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

public class TreeDeep {
	 static class TreeNode{
		 int val;
		 TreeNode left;
		 TreeNode right;
		 int deep;
		 TreeNode(int val, TreeNode left, TreeNode right, int deep){
			 this.val = val;
			 this.left = left;
			 this.right = right;
			 this.deep = deep;
		 }
	 }
	 
	 public static void main(String[] args) {
		 TreeNode node7 = new TreeNode(7,null,null,0);
		 TreeNode node6 = new TreeNode(6,node7,null,0);
		 TreeNode node5 = new TreeNode(5,null,null,0);
		 TreeNode node4 = new TreeNode(4,null,null,0);
		 TreeNode node3 = new TreeNode(3,node6,null,0);
		 TreeNode node2 = new TreeNode(2,node4,node5,0);
		 TreeNode node1 = new TreeNode(1,node2,node3,0);
		 //System.out.println(minDepth(node1));
		 System.out.println(minDepth2(node1));
	}
	
	 //广度优先
	 public static int minDepth2(TreeNode root) {
		 if(root == null) {
			 return 0;
		 }
		 Queue<TreeNode> queue = new LinkedList<TreeNode>();
		 root.deep = 1;
		 queue.offer(root);
		 while(!queue.isEmpty()) {
			 TreeNode node = 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;
	 }
	 
}

总结

深度优先是将叶子节点的深度设置为1,广度优先是将根节点深度设置为1。
在时间复杂度上,深度优先和广度优先都是O(n);
在空间复杂度上,深度优先取决于树的深度,为O(logn),广度优先的空间复杂度为O(n)。

最长连续递增序列

思路

贪心算法。
设定两个指针i和j。首先i指向0的位置,j指向1的位置。设定count初始值为1,max初始值为0。
(1)如果nums[i]小于等于nums[j],则说明可以继续进行,i++,j++,count++,同时取count和max中的最大值;
(2)相反,将j指向的值给i,然后j++。

package test;

public class MaxSeq {
	public static void main(String[] args) {
		int[] nums = new int[] {1,2,3,2,3,4,3,4,5,6,7};
		System.out.println(fingLength(nums));
	}
	//贪心算法
	public static int fingLength(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 static int fingLength1(int[] nums) {
		int i = 0, j = 1;
		int count = 1, max = 0;
		while(j < nums.length) {
			if(nums[i] <= nums[j]) {
				i++;j++;
				count++;
				max = Math.max(count, max);
			}else {
				i = j;
				j++;
				count = 1;
			}
		}
		return max;
	}

}

柠檬水找零

在柠檬水摊上,每一杯柠檬水售价5美元,顾客排队购买,一次一杯。每位顾客只买一杯柠檬水,然后像你付5美元、10美元或者20美元,必须正确给每个顾客找零,注意一开始你手头没有任何零钱。如果你可以给每位顾客找零返回true,否则返回false。

实现

package test;

public class lemonChange {
	public static void main(String[] args) {
		System.out.println(change(new int[] {5,5,10}));
	}
	public static boolean change(int[] bills) {
		int five = 0, ten = 0;
		for(int bill : bills) {
			if(bill == 5) {
				five++;
			}else if(bill == 10){
				if(five == 0) {
					return false;
				}
				five--;
				ten++;
			}else if(bill == 20) {
				if(five > 0 && ten > 0) {
					five--;
					ten--;
				}else if(five >= 3) {
					five -= 3;
				}else {
					return false;
				}	
			}
		}
		return true;
	}
}

贪心算法

贪心算法主要的思想就是在对问题求解时,总是作出当前最优解的选择。贪心算法适用于每一步的贪心选择最终可以导致问题最优解的情况。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值