第 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. python+pytesseract识别图片文字

    此文只介绍一下python+pytesseract识别一些简单图片的数字,字母和汉字.如图1 import pytesseract from PIL import Image,ImageEnhance ...

  2. You Don't Know JS阅读笔记

    JS特性查漏补缺 [1,2,3]=="1,2,3" //true 前者会隐式转换,用逗号组合成字符串 212>'22' //true 有一个值不是number就会隐式转换成n ...

  3. 【JSON】Python读取JSON文件报错json.decoder.JSONDecodeError的问题

    报错 json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line * column * ...

  4. Jenkins在windows环境下的3种部署方式

    本文主要介绍Jenkins在windows环境下的3种部署方式: (1)官网下载jenkins.msi文件直接安装.jenkins官网地址:https:/jenkins.io/zh/ (2)jenki ...

  5. 【Delphi11】「Embarcadero.Delphi.11.0.v28.0.42600.6491.Lite.v17.0分享」

    [Delphi11]转存或下载后将后缀名".exe"删除即可,或者直接右击解压缩也可.「Embarcadero.Delphi.11.0.v28.0.42600.6491.Lite. ...

  6. CentOS 7 部署Memcached服务器——超级详细

    操作系统:CentOS 7.x 64位实现目的:安装部署Memcached服务器 一.防火墙设置CentOS 7.x默认使用的是firewall作为防火墙,这里改为iptables防火墙. 1.关闭f ...

  7. mysql授权、导入等基本操作

    1.授权: mysqladmin -uroot password rootpwd mysql -uroot -prootpwd mysql -e "INSERT INTO user (Hos ...

  8. HBuilder uniapp手机定位

    // 获取当前位置 getPosition: function() { this.GetLocation(function(res) { if (res) { this.longitude = res ...

  9. django_模板层的变量和标签

    一.模板层的变量 1.能传递到模板层的数据类型:str(字符串).list(数组).dict(字典).obj(类实例化的对象).fun(函数)等. 2.在模板中使用变量的方法: (1)字符串:{{ 变 ...

  10. shell命令查找文件

    1.find命令的参数下面是find命令一些常用参数的例子,有用到的时候查查就行了,像上面前几个贴子,都用到了其中的的一些参数,也可以用man或查看论坛里其它贴子有find命令手册使用name选项文件 ...