第 28 天

搜索与回溯算法(困难)

剑指 Offer 37. 序列化二叉树

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

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

提示:输入输出格式与 LeetCode 目前使用的方式一致,详情请参阅 LeetCode 序列化二叉树的格式。你并非必须采取这种方式,你也可以采用其他的方法解决这个问题。

示例:

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

题解思路:层次遍历、递归下降

层次遍历:

public class Codec {
// Encodes a tree to a single string.
public String serialize(TreeNode root) {
if (root == null) {
return "[]";
}
StringBuffer res = new StringBuffer("[");
Queue<TreeNode> queue = new LinkedList<TreeNode>();
queue.add(root);
while (!queue.isEmpty()) {
TreeNode node = queue.poll();
if (node != null) {
res.append(node.val + ",");
queue.add(node.left);
queue.add(node.right);
}
else res.append("null,");
}
res.deleteCharAt(res.length()-1);
res.append("]");
return res.toString();
}
// Decodes your encoded data to tree.
public TreeNode deserialize(String data) {
if (data.equals("[]")) {
return null;
}
String[] vals = data.substring(1, data.length()-1).split(",");
TreeNode root = new TreeNode(Integer.parseInt(vals[0]));
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
int i = 1;
while (!queue.isEmpty()) {
TreeNode temp = queue.poll();
if (!vals[i].equals("null")) {
temp.left = new TreeNode(Integer.parseInt(vals[i]));
queue.add(temp.left);
}
i ++;
if (!vals[i].equals("null")) {
temp.right = new TreeNode(Integer.parseInt(vals[i]));
queue.add(temp.right);
}
i ++;
}
return root;
}
}

复杂度:时间 O(n) 空间O(n)

递归下降:

public class Codec {
public String serialize(TreeNode root) {
if (root == null) {
return "X";
}
String left = "(" + serialize(root.left) + ")";
String right = "(" + serialize(root.right) + ")";
return left + root.val + right;
} public TreeNode deserialize(String data) {
int[] ptr = {0};
return parse(data, ptr);
} public TreeNode parse(String data, int[] ptr) {
if (data.charAt(ptr[0]) == 'X') {
++ptr[0];
return null;
}
TreeNode cur = new TreeNode(0);
cur.left = parseSubtree(data, ptr);
cur.val = parseInt(data, ptr);
cur.right = parseSubtree(data, ptr);
return cur;
} public TreeNode parseSubtree(String data, int[] ptr) {
++ptr[0]; // 跳过左括号
TreeNode subtree = parse(data, ptr);
++ptr[0]; // 跳过右括号
return subtree;
} public int parseInt(String data, int[] ptr) {
int x = 0, sgn = 1;
if (!Character.isDigit(data.charAt(ptr[0]))) {
sgn = -1;
++ptr[0];
}
while (Character.isDigit(data.charAt(ptr[0]))) {
x = x * 10 + data.charAt(ptr[0]++) - '0';
}
return x * sgn;
}
}

复杂度:时间 O(n) 空间O(n)

剑指 Offer 38. 字符串的排列

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

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

示例:

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

限制:

1 <= s 的长度 <= 8

题解思路:回溯、dfs

回溯:

class Solution {
List<String> rec;
boolean[] vis; public String[] permutation(String s) {
int n = s.length();
rec = new ArrayList<>();
vis = new boolean[n];
char[] arr = s.toCharArray();
Arrays.sort(arr);
StringBuffer buffer = new StringBuffer();
backtrack(arr, 0, n, buffer);
int size = rec.size();
String[] recArray = new String[size];
for (int i = 0; i < size; i ++) {
recArray[i] = rec.get(i);
}
return recArray;
} public void backtrack(char[] arr, int i, int n, StringBuffer perm) {
if (i == n) {
rec.add(perm.toString());
return;
}
for (int j = 0; j < n; j++) {
if (vis[j] || (j > 0 && !vis[j - 1] && arr[j - 1] == arr[j])) {
continue;
}
vis[j] = true;
perm.append(arr[j]);
backtrack(arr, i + 1, n, perm);
perm.deleteCharAt(perm.length() - 1);
vis[j] = false;
}
}
}

复杂度:时间 O(n) 空间 O(n)

dfs:

class Solution {
List<String> res = new LinkedList<>();
char[] c;
public String[] permutation(String s) {
c = s.toCharArray();
dfs(0);
return res.toArray(new String[res.size()]);
}
void dfs(int x) {
if(x == c.length - 1) {
res.add(String.valueOf(c)); // 添加排列方案
return;
}
HashSet<Character> set = new HashSet<>();
for(int i = x; i < c.length; i++) {
if(set.contains(c[i])) continue; // 重复,因此剪枝
set.add(c[i]);
swap(i, x); // 交换,将 c[i] 固定在第 x 位
dfs(x + 1); // 开启固定第 x + 1 位字符
swap(i, x); // 恢复交换
}
}
void swap(int a, int b) {
char tmp = c[a];
c[a] = c[b];
c[b] = tmp;
}
}

复杂度:时间 O(n) 空间 O(n)

剑指 offer 第 28 天的更多相关文章

  1. 【剑指offer】28. 对称的二叉树

    剑指 Offer 28. 对称的二叉树 知识点:二叉树:递归 题目描述 请实现一个函数,用来判断一棵二叉树是不是对称的.如果一棵二叉树和它的镜像一样,那么它是对称的. 示例 输入:root = [1, ...

  2. 剑指offer 面试28题

    面试28题: 题目:对称的二叉树题: 请实现一个函数,用来判断一颗二叉树是不是对称的.注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的 解题思路: 可以定义一种遍历算法,先遍历右子节点再遍 ...

  3. 剑指offer(28)数组中出现次数超过一半的数

    题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2. ...

  4. 剑指 offer set 28 实现 Singleton 模式

    singleton 模式又称单例模式, 它能够保证只有一个实例. 在多线程环境中, 需要小心设计, 防止两个线程同时创建两个实例. 解法 1. 能在多线程中工作但效率不高 public sealed ...

  5. 【剑指Offer】28、数组中出现次数超过一半的数字

      题目描述:   数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.   例如:输入如下所示的一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过 ...

  6. 【剑指Offer】剑指offer题目汇总

      本文为<剑指Offer>刷题笔记的总结篇,花了两个多月的时间,将牛客网上<剑指Offer>的66道题刷了一遍,以博客的形式整理了一遍,这66道题属于相对基础的算法题目,对于 ...

  7. 剑指Offer:对称的二叉树【28】

    剑指Offer:对称的二叉树[28] 题目描述 请实现一个函数,用来判断一颗二叉树是不是对称的.注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的. 题目分析 Java题解 /* publi ...

  8. [剑指 Offer 28. 对称的二叉树]

    剑指 Offer 28. 对称的二叉树 请实现一个函数,用来判断一棵二叉树是不是对称的.如果一棵二叉树和它的镜像一样,那么它是对称的. 例如,二叉树 [1,2,2,3,4,4,3] 是对称的. 1 / ...

  9. 【Java】 剑指offer(28) 对称的二叉树

    本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集   题目 请实现一个函数,用来判断一棵二叉树是不是对称的.如果一棵二叉树和它 ...

  10. 《剑指offer》面试题28:字符串的排列(牛客网版本) java

    题目描述 输入一个字符串,按字典序打印出该字符串中字符的所有排列.例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba. 输入描述: 输 ...

随机推荐

  1. textarea兼容问题

    一.IOS 中不允许输入 <textarea contenteditable="true"></textarea> textarea { -webkit-u ...

  2. mysqld 打开连接卡

    把client的ip写在mysql服务器的/etc/hosts文件里 echo [ip] [hostname] >>/etc/hosts

  3. ESXI不重启增加硬盘空间更新

    ESXI虚拟机Linux添加新磁盘后,可以通过重新扫描SCSI总线,在不重启虚拟机的情况下添加SCSI设备在线扩容磁盘(不停机)后,添加磁盘无法识别的问题,尝试了多种办法,最终通过重新扫描SCSI设备 ...

  4. c++学习1 基础关键词

    一 "const" 修饰变量 只能被初始化和读取,不能被赋值更改,且必需初始化,不初始化的话会因为读取到随机数而报错. example: const int date=100; c ...

  5. oracle相关知识

    1. 给表字段添加注释的语法 comment on column 表名.字段名 is '注释信息'; 2. 数据库字段重命名 alter table ORGAN_PARTER_EXT_TWO rena ...

  6. COLMAP论文阅读笔记——sfm算法、不定期更新

    文章目录 structure from motion revisited 第一步 对应点搜索 特征提取feature extraction 匹配matching 几何验证geometric verif ...

  7. Tacotron2论文阅读笔记

    Tacotron2 NATURAL TTS SYNTHESIS BY CONDITIONING WAVENET ON MEL SPECTROGRAM PREDICTIONS论文阅读笔记 先推荐一篇比较 ...

  8. Android studio Internet跳转活动

    <?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android=" ...

  9. flutter 环境配置以及我的第一个flutter程序(Hello World)

    电脑配置: 操作系统: Windows 7 或更高版本 (64-bit) 磁盘空间: 400 MB (不包括Android Studio的磁盘空间). Windows下所需安装有: 1.Flutter ...

  10. centos6放行防火墙8080端口操作

    1. 进入防火墙文件: [ vi /etc/sysconfig/iptables ] 2. 放行8080端口: [ -A RH-Firewall-1-INPUT -m state --state NE ...