剑指 Offer II 054. 所有大于等于节点的值之和 与 剑指 Offer II 033. 变位词组

57 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第6天,点击查看活动详情

1. 题目与解析

给定一个二叉搜索树,请将它的每个节点的值替换成树中大于或者等于该节点值的所有节点值之和。

提醒一下,二叉搜索树满足下列约束条件:

  • 节点的左子树仅包含键 小于 节点键的节点。
  • 节点的右子树仅包含键 大于 节点键的节点。
  • 左右子树也必须是二叉搜索树。

image.png

输入:root = [4,1,6,0,2,5,7,null,null,null,3,null,null,null,8]

输出:[30,36,21,36,35,26,15,null,null,null,33,null,null,null,8]

输入: root = [0,null,1]

输出: [1,null,1]

根据题目可知,在二叉搜索树中,对于任意一个节点,其左子树以及父树的值都是比该结点大的。

我们以上述例子的结点6为例:

image.png

红色部分是结点6的父节树,黄色部分是结点6的左子树,绿色为结点6的本身,这三部分值和就是我们需要修改的新树结点的值。

因此,自然而言的,我们可以利用中序遍历整棵二叉搜索树,在一次遍历的过程中更新结点的值。

2. 题解

在这里,选择使用递归的方式来实现二叉搜索树的中序遍历:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    int tmp;

    public TreeNode convertBST(TreeNode root) {
        if (root == null) return null;

        convertBST(root.right);
        tmp += root.val;
        root.val = tmp;
        convertBST(root.left);
        return root;
    }
}

另外,我们也可以使用迭代的方式借助栈结构来实现中序遍历。

3. 题目与解析

给定一个字符串数组 strs ,将 变位词 组合在一起。 可以按任意顺序返回结果列表。

注意: 若两个字符串中每个字符出现的次数都相同,则称它们互为变位词。

输入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"]

输出: [["bat"],["nat","tan"],["ate","eat","tea"]]

输入: strs = [""]

输出: [[""]]

输入: strs = ["a"]

输出: [["a"]]

有题意可得,变位词 就是指字符出现的次数都相同的字符串,因此,我们可以选择用一种编码格式给字符串编码,使字符出现的次数都相同的字符串相等,这样我们就能通过哈希表过滤出相等的变位词,之后按照要求输出即可。

4. 题解

class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        Map<String, List<String>> map = new HashMap<>();
        List<List<String>> ans = new ArrayList<>();

        for (String str: strs) {
            int[] counts = new int[26];
            for (int i = 0; i < str.length(); i++) {
                counts[str.charAt(i) - 'a']++;
            }
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < 26; i++) {
                sb.append(i + 'a');
                sb.append(counts[i]);
            }
            String key = sb.toString();
            if (!map.containsKey(key)) {
                map.put(key, new ArrayList<>());
            }
            map.get(key).add(str);
        }

        for(Map.Entry<String, List<String>> e: map.entrySet()) {
            ans.add(e.getValue());
        }

        return ans;
    }
}