110. 平衡二叉树

 

110. 平衡二叉树

给定一个二叉树,判断它是否是高度平衡的二叉树。

本题中,一棵高度平衡二叉树定义为:

一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。

示例 1:

给定二叉树 [3,9,20,null,null,15,7]

    3
   / \
  9  20
      /  \
   15   7
返回 true 。

示例 2:

给定二叉树 [1,2,2,3,3,null,null,4,4]

        1
        / \
      2    2
      / \
    3    3
   / \
 4   4
返回 false 。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/balanced-binary-tree
 

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
 boolean result = true;
 public boolean isBalanced(TreeNode root) {
     isBalanced1(root);
     return result;
 }
 
 public int  isBalanced1(TreeNode root) {
     if(root == null){
    	 return 0;
     }
     int lh = 0;
     int rh = 0;
     
     if(root.left != null){
    	 lh = isBalanced1(root.left);
     }
     if(root.right != null){
    	 rh  = isBalanced1(root.right);
     }
     if(Math.abs(lh - rh) > 1){
    	 result = false;
     }
     return Math.max(lh, rh) + 1;
 }
}

111. 二叉树的最小深度

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

最小深度是从根节点到最近叶子节点的最短路径上的节点数量。

说明: 叶子节点是指没有子节点的节点。

示例:

给定二叉树 [3,9,20,null,null,15,7],

     3
    / \
  9  20
      /  \
   15   7
返回它的最小深度  2.

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/minimum-depth-of-binary-tree
 

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public int minDepth(TreeNode root) {
        
 

     if(root == null){
    	 return 0;
     }
     
     if ((root.left == null) && (root.right == null)) {
         return 1;
       }

     int lh = 0;
     int rh = 0;
     int min_depth = Integer.MAX_VALUE;
     
     if(root.left != null){
    	 lh = minDepth(root.left);
    	 min_depth =  Math.min(lh, min_depth);
     }
     if(root.right != null){
    	 rh  = minDepth(root.right);
    	 min_depth =  Math.min(rh, min_depth);
     }
 
     return  min_depth + 1;
 
 
    }
}

给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。

说明: 叶子节点是指没有子节点的节点。

示例: 
给定如下二叉树,以及目标和 sum = 22,

                5
               / \
            4    8
           /      / \
        11    13  4
        /  \            \
      7    2           1
返回 true, 因为存在目标和为 22 的根节点到叶子节点的路径 5->4->11->2。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/path-sum

 
 public boolean hasPathSum(TreeNode root, int sum) {
	 if(root ==  null){
		 return  false;
	 }
	 sum -= root.val;
	 if(sum == 0 && root.left == null && root.right == null){
		 return true;
	 }
	 return hasPathSum(root.left, sum) || hasPathSum(root.right, sum);
 }
 

 

113. 路径总和 II

给定一个二叉树和一个目标和,找到所有从根节点到叶子节点路径总和等于给定目标和的路径。

说明: 叶子节点是指没有子节点的节点。

示例:
给定如下二叉树,以及目标和 sum = 22,

               5
               / \
            4      8
           /        / \
         11    13  4
         /  \           / \
       7    2        5   1
返回:

[
   [5,4,11,2],
   [5,8,4,5]
]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/path-sum-ii
 

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
   List<List<Integer>> ans = new ArrayList<>();
  List<Integer> path = new ArrayList<>();
  public List<List<Integer>> pathSum(TreeNode root, int sum) {
      helper(root, sum );
      return ans;
  }
  public void helper(TreeNode node, int sum) {
		 if (node == null) {
			 return;
	     }

	  // 将沿途到节点加入到path中
	  sum -= node.val;
	  path.add(node.val);
	
	  // 遍历到叶节点
	  if (node.left == null && node.right == null) {
	      // 如果这是一条可行的路径,才复制path的结果到ans
	      if (sum == 0)
	          ans.add(new ArrayList<>(path));
	      else{
	    	  path.remove(path.size() - 1);
	    	  return ;
	      }
	  }
	  helper(node.left, sum );
      helper(node.right, sum );
	  
	  // 回溯
  	  path.remove(path.size() - 1);
  }
 
 
}

118. 杨辉三角

给定一个非负整数 numRows,生成杨辉三角的前 numRows 行。

在杨辉三角中,每个数是它左上方和右上方的数的和。

 

输入: 5
输出:
[
     [1],
    [1,1],
   [1,2,1],
  [1,3,3,1],
 [1,4,6,4,1]
]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/pascals-triangle

 

方法:动态规划
思路

如果能够知道一行杨辉三角,我们就可以根据每对相邻的值轻松地计算出它的下一行。

算法

虽然这一算法非常简单,但用于构造杨辉三角的迭代方法可以归类为动态规划,因为我们需要基于前一行来构造每一行。

首先,我们会生成整个 triangle 列表,三角形的每一行都以子列表的形式存储。然后,我们会检查行数为 0的特殊情况,否则我们会返回 [1]。如果 numRows > 0,那么我们用 [1]作为第一行来初始化 triangle with [1],并按如下方式继续填充:

 

 
  public List<List<Integer>> generate(int numRows) {
      List<List<Integer>> triangle = new ArrayList<List<Integer>>();
      // First base case; if user requests zero rows, they get zero rows.
      if (numRows == 0) {
          return triangle;
      }
      // Second base case; first row is always [1].
      triangle.add(new ArrayList<>());
      triangle.get(0).add(1);

      for (int rowNum = 1; rowNum < numRows; rowNum++) {
          List<Integer> row = new ArrayList<>();
          List<Integer> prevRow = triangle.get(rowNum-1);
          // The first row element is always 1.
          row.add(1);
          // Each triangle element (other than the first and last of each row)
          // is equal to the sum of the elements above-and-to-the-left and
          // above-and-to-the-right.
          for (int j = 1; j < rowNum; j++) {
              row.add(prevRow.get(j-1) + prevRow.get(j));
          }
          // The last row element is always 1.
          row.add(1);
          triangle.add(row);
      }
      return triangle;
  }
 

46. 全排列
 

给定一个没有重复数字的序列,返回其所有可能的全排列。

示例:

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/permutations
 

class Solution {

  List<List<Integer>> lists= new ArrayList<>();
  List<Integer> list = new ArrayList<>();
  public List<List<Integer>> permute(int[] nums) {
      permute1(nums, 0, nums.length -1);
      return lists;
  }
 
 public  void  permute1(int[] nums,int start ,int end) {
	 
     if(start == end ){
    	 for (int i = 0; i < nums.length; i++) {
			list.add(nums[i]);
		}
    	 lists.add(new ArrayList<>(list));
    	 list.clear();
     }
	 
	 for (int i = start; i <= end; i++) {
		swap(nums, i, start);
		permute1(nums, start + 1 , end);
		swap(nums, start, i);
		 
	}
	 
  }
 
 public void swap(int[] nums,int i , int k){
	 
	 int temp = nums[i];
	 nums[i] = nums[k];
	 nums[k] = temp;
 }
}

23. 合并K个排序链表

合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。

示例:

输入:
[
  1->4->5,
  1->3->4,
  2->6
]
输出: 1->1->2->3->4->4->5->6

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/merge-k-sorted-lists
 

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
        
	    PriorityQueue<Integer> qun  = new PriorityQueue<>();
	    for (int i = 0; i < lists.length; i++) {
			while(lists[i]  != null){
				qun.add(lists[i].val);
				lists[i] = lists[i].next;
			}
		}
	    ListNode head = new ListNode(-1);
	    ListNode next = head;
	    while(!qun.isEmpty()){
	    	next.next = new ListNode(qun.remove());
	    	next = next.next;
	    }
	    
		return head.next;
		 
	 
    }
}

121. 买卖股票的最佳时机

给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。

如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润。

注意你不能在买入股票前卖出股票。

示例 1:

输入: [7,1,5,3,6,4]
输出: 5
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
     注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格。
示例 2:

输入: [7,6,4,3,1]
输出: 0
解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock 

第一种解法
public int maxProfit(int[] prices) {
	    	if(prices== null || prices.length == 0){
	    		return 0;
	    	}
	         int[] dp = new int[prices.length];
	    	for (int i = 0; i < prices.length; i++) {
				  int max = Integer.MIN_VALUE;
				  for (int j = i+1; j < prices.length; j++) {
					if(prices[j] - prices[i] > max){
						max = prices[j] - prices[i];
					}
				}
				 if(max > 0 ){
					 dp[i] = max;
				 }else{
					 dp[i] = 0;
				 }
				  
			}
	    	
	    	int result  = dp[0];
	    	for (int i = 1; i < dp.length; i++) {
				if(dp[i] > result){
					result = dp[i];
				}
			}
	    	return result;
	    	 
	    }
	    
	    
 第二种解法
 
	    public int maxProfit1(int prices[]) {
	        int maxprofit = 0;
	        for (int i = 0; i < prices.length - 1; i++) {
	            for (int j = i + 1; j < prices.length; j++) {
	                int profit = prices[j] - prices[i];
	                if (profit > maxprofit)
	                    maxprofit = profit;
	            }
	        }
	        return maxprofit;
	    }

第三种
    public int maxProfit2(int prices[]) {
	        int minprice = Integer.MAX_VALUE;
	        int maxprofit = 0;
	        for (int i = 0; i < prices.length; i++) {
	            if (prices[i] < minprice)
	                minprice = prices[i];
	            else if (prices[i] - minprice > maxprofit)
	                maxprofit = prices[i] - minprice;
	        }
	        return maxprofit;
	    }

第三种的思路

假设给定的数组为:

[7, 1, 5, 3, 6, 4]

如果我们在图表上绘制给定数组中的数字,我们将会得到:

使我们感兴趣的点是上图中的峰和谷。我们需要找到最小的谷之后的最大的峰。
我们可以维持两个变量——minprice 和 maxprofit,它们分别对应迄今为止所得到的最小的谷值和最大的利润(卖出价格与最低价格之间的最大差值)。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值