leetcode 109 以及 leetcode 109 路径总和二

148 阅读1分钟

leetcode 109是根据升序链表构造一个BST,通常有两种方法: 1.链表转换为数组。 2.使用快慢指针定位根节点。 但是还有一个利用BST的特性,使用中序遍历、分治来直接构造BST。 leetcode 113是根据二叉树的值是否等于目标值,通常有两种方法: 1.深度优先遍历。 2.广度优先遍历。

思路:

关于leetcode 109 使用中序遍历进行构造二叉树,首先进行一次遍历知道链表的长度,然后求出mid进行分治,根据中序遍历的特性,首先要遍历左节点,在遍历根节点、右节点,最后注意写好递归结束条件即可。

public TreeNode sortedListToBst(ListNode head){
    ListNode listNode = head;
    int length = 0;
    while(listNode != null){
        length++;
        listNode = listNode.next;
    }
    TreeNode treeNode = DFSOrder(0, length - 1);
    return treeNode;
}
private TreeNode DFSOrder(int start, int end){
    if (start > end) return null;
    int mid = start+(end - start)/2;
    TreeNode left = DFSOrder(start, mid-1);
    TreeNode root = new TreeNode(node1.val);
    root.left = left;
    node1 = node1.next;
    root.right = DFSOrder(mid+1,end);
    return root;
}

关于leetcode 103路径总和

深度优先遍历是这一道的题最容易想到的解法,几乎没有什么好说的,只要读清楚题目,一定要注意有负数,不要随便进行剪枝,这道题在我看来是不需要剪枝的。

    private List<List<Integer>> res = new ArrayList<>();
    public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
        backtrackTree(root,new ArrayList<>(),0,targetSum);
        return res;
    }
    private void backtrackTree(TreeNode node, List<Integer> list, int sum, int targetSum) {
        if (node == null) return;
        if (sum + node.val == targetSum) {
//            boolean flag = node.left != null && node.right != null;
            if ((node.left == null) && (node.right == null)) {
                list.add(node.val);
                res.add(new ArrayList<>(list));
                list.remove(list.size()-1);
                return;
            }
        }

        if (node.left != null) {
            list.add(node.val);
            backtrackTree(node.left, list, sum+node.val, targetSum);
            list.remove(list.size()-1);
        }
        if (node.right != null){
            list.add(node.val);
            backtrackTree(node.right, list,sum+node.val, targetSum);
            list.remove(list.size()-1);
        }

    }

广度优先遍历,这种思路对于这种题来说就可能就比较难想到,相对于深度优先遍历可能复杂一些,因为需要自己进行维护队列,对每一层的树节点进行保存以及及时移除,而这一道题就还需要额外维护一个队列,因为需要保存路径,关于保存这一条路径的总数和,是可以直接改变下一个节点的值,让它变为这条路径的总和值。注意:当遍历完了左子树,一定要对于保存节点的list要进行删除最后一位数值,否则遍历同一层面的右子树的时候就会在该右子树前面多出一个结点值是同一层面的左子树结点。

private List<List<Integer>> res = new ArrayList<>();
public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
    Deque<TreeNode> queue = new LinkedList<>();
    Deque<List<Integer>> lists = new LinkedList<>();
    queue.addLast(root);
    List<Integer> list = new ArrayList<>();
    list.add(root.val);
    lists.add(list);
    while(!queue.isEmpty()){
       int length = queue.size();
        for (int i = 0; i < length; i++) {
            TreeNode treeNode = queue.removeFirst();
            List<Integer> list1 = lists.removeFirst();
            if (treeNode.left == null && treeNode.right == null && treeNode.val == targetSum) {
                res.add(new ArrayList<>(list1));
            }
            if (treeNode.left != null){
                list1.add(treeNode.left.val);
                lists.addLast(new ArrayList<>(list1));
                treeNode.left.val += treeNode.val;
                queue.addLast(treeNode.left);
                list1.remove(list1.size()-1);
            }
            if (treeNode.right != null){
                list1.add(treeNode.right.val);
                lists.addLast(new ArrayList<>(list1));
                treeNode.right.val += treeNode.val;
                queue.addLast(treeNode.right);
            }
        }
    }

    return res;
}