Hot 100题刷题 Day 5

Day5

翻转二叉树

  1. 题目:翻转一棵二叉树,使其左右子树互换,形式如下图片:
     4                                                                    4
   /   \                                                               /    \
  7     2                          ->                                 2      7       
 / \   / \                                                           / \    / \
9   6 3   1                                                         1   3  6   9
  1. 题目解析:二叉树的互换,实际上是左右子树元素的互换,由于树的基本性质,可以较为简单的想到采用递归的方式,但左右子树互换的时候,需要保存互换的值,避免交换错误,具体代码如下:
class Solution {

    public TreeNode invertTree(TreeNode root) {
        return tranverse(root);
    }
    public TreeNode tranverse(TreeNode root){
        if(root == null)
            return null;
        //使用 tmp 节点存放交换后的左右子树的元素引用
        TreeNode tmp = tranverse(root.right);
        root.right = tranverse(root.left);
        root.left = tmp;
        //返回交换成功后的左右子树
        return root;
    }
}

环形链表

  1. 题目:判断一个链表中是否产生了环,注意,不改变链表原来结构,同时,空间复杂度为 \(O(1)\)
  2. 题目解析:可以循环遍历时使用哈希表记录引用地址,看哈希表中是否已经存在引用。本解采用的主要思路是龟兔思路,快慢指针在成环的链表中,经历 \(n\) 圈后,必会相遇,代码如下:
public class Solution {
    public boolean hasCycle(ListNode head) {
        if(head == null || head.next == null)
            return false;
        //快慢指针的初值,使其都能进入循环体中
        ListNode slow = head;
        ListNode quick = head.next;
        while(slow != quick){
            //如果快指针能到达 null 说明并没有成环
            if(quick == null || quick.next == null)
                return false;
            slow = slow.next;
            quick = quick.next.next;
        }
        return true;
    }
}

组合总和

  1. 题目:给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。注意,candidates 中的元素可以被无限次选取,同时,像 2,2,3 和 3,2,2 这样的序列被认为是重复序列,不能出现在答案中。
  2. 题解:很明显的搜索回溯问题,为了避免重复序列,应该设置一个 begin 序号来标明之前元素不能再选取。同时,搜索回溯的过程还应当适当剪枝(本题解是基于排序基础上的剪枝),代码如下:
class Solution {
    //存放最终的答案
    List<List<Integer>> ans = new ArrayList<>();

    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        if(candidates == null || candidates.length == 0)
            return null;
        //对元素进行排序便于后面的剪枝
        Arrays.sort(candidates);
        dfs(candidates, target, new ArrayList<Integer>(), 0);
        return ans;
    }
    public void dfs(int[] candidates, int target, List<Integer> stack, int index){
        //target 等于 0 说明已经得出一个题解
        if(target == 0){
            ans.add(new ArrayList<>(stack));
            return;
        }
        for(int i = index; i < candidates.length; i ++){
            //剪枝,小元素都超过目标,大元素更不行
            if(target - candidates[i] < 0)
                break;
            stack.add(candidates[i]);
            dfs(candidates, target - candidates[i], stack, i);
            //添加完题解后,删去刚刚加入的元素,继续遍历
            stack.remove(stack.size() - 1);
        }
    }
}
posted @ 2021-01-23 12:29  Lichit  阅读(94)  评论(0)    收藏  举报