剑指Offer 37 38

604 阅读1分钟

这是我参与8月更文挑战的第18天,活动详情查看:8月更文挑战

剑指 Offer 37. 序列化二叉树

题目

请实现两个函数,分别用来序列化和反序列化二叉树。

你需要设计一个算法来实现二叉树的序列化与反序列化。这里不限定你的序列 / 反序列化算法执行逻辑,你只需要保证一个二叉树可以被序列化为一个字符串并且将这个字符串反序列化为原始的树结构。

示例:

img

输入:root = [1,2,3,null,null,4,5]
输出:[1,2,3,null,null,4,5]

方法一

前序遍历:利用前序遍历将节点值和空结点用字符串的形式存下来,其中空结点用&来表示,另外结点之间用#分隔;还原二叉树时,再做一遍前序遍历即可;

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Codec {
​
    // Encodes a tree to a single string.
    public String serialize(TreeNode root) {
        return dfs1(root);
    }
    String dfs1(TreeNode root) {
        if (root == null) return "&#";
        String res = String.valueOf(root.val) + "#";
        res += dfs1(root.left);
        res += dfs1(root.right);
        return res;
    }
​
    String data;
    // Decodes your encoded data to tree.
    public TreeNode deserialize(String _data) {
        data = _data;
        return dfs2();
    }
    TreeNode dfs2() {
        int i = 0;
        while(data.charAt(i) != '#') i ++;
        String num = data.substring(0, i);
        if (i < data.length() - 1) data = data.substring(i + 1);
​
        if (num.equals("&")) return null;
        TreeNode root = new TreeNode(Integer.parseInt(num));
        root.left = dfs2();
        root.right = dfs2();
        return root;
    }
}
​
// Your Codec object will be instantiated and called as such:
// Codec codec = new Codec();
// codec.deserialize(codec.serialize(root));

时间复杂度: O(n)

空间复杂度: O(n)

注意: 前序遍历中包含空结点,则可以唯一确定一颗二叉树

剑指 Offer 38. 字符串的排列

题目

输入一个字符串,打印出该字符串中字符的所有排列。

你可以以任意顺序返回这个字符串数组,但里面不能有重复元素。

示例:

输入:s = "abc"
输出:["abc","acb","bac","bca","cab","cba"]

限制:

  • 1 <= s 的长度 <= 8

方法一

回溯:为了防止重复元素如,a1='a'a2='a',结果中出现a1a2a2a1的情况,给重复元素之间规定一个顺序,即只有当重复元素中的位于前面的用了才能用后面的;

class Solution {
    List<String> res = new LinkedList<>();
    String path = "";
    char[] c;
    boolean[] st;
    public String[] permutation(String s) {
        c = s.toCharArray();
        Arrays.sort(c);
        st = new boolean[c.length];
        dfs(0);
        return res.toArray(new String[res.size()]);
    }
    void dfs(int index) {
        if (index == c.length) {
            res.add(path);
            return ;
        }
        for (int i = 0; i < c.length; i ++ ) {
            if (i != 0 && c[i] == c[i - 1] && !st[i - 1]) continue; //规定顺序
            if (!st[i]) {
                path += c[i];
                st[i] = true;
                dfs(index + 1);
                st[i] = false;
                path = path.substring(0, path.length() - 1);
            }
        }
    }
}