第 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. HTML复习(18.图片样式)

    重点 掌握图片样式属性(大小.边框.对齐)了解float属性 图片大小在CSS中,我们也是使用width和height这2个属性来定义图片的大小(也就是宽度和高度).在实际开发中,如果你需要多大的图片 ...

  2. Django 介绍及环境准备

    Django介绍: Django(发音:[`dʒæŋɡəʊ])是基于Python的Web框架,它是开源的,免费的. Django使构建更好的web应用程序变得更容易.更快.代码更少 django的MT ...

  3. Java 基础(二)

    类的初始 类中包括:属性,方法. 快速使用 我们都是人,而人的共同特点有很多. 比如:名字,年龄,性别,吃饭,睡觉... // 定义类 public class Person { // 定义属性 St ...

  4. Day16-异常

    异常机制 一.Error和Exception 1.什么是异常 2.异常体系结构 3.Error和Exception Error Exception 二.捕获和抛出异常 1.异常处理机制 抛出异常 捕获 ...

  5. java Comparator和Comparable的区别?

    参考:https://blog.csdn.net/m0_71087031/article/details/124850080 Comparable是一个内比较器,可以和自己比较的 Comparator ...

  6. idea设置svn忽略文件

    第一步: 第二步: 第三步:

  7. Flutter Web预览时白屏解决方法

    原因是因为运行 flutter run 是自动选择渲染器 桌面端WEB浏览器默认使用  CanvasKit渲染器 移动端WEB浏览器默认使用  HTML渲染器 问题就出在了CanvasKit渲染器,他 ...

  8. visio2019 破解

    链接:https://pan.baidu.com/s/14AU8GFXhgjp87pK1bIK8UA?pwd=ju61 提取码:ju61 --来自百度网盘超级会员V5的分享 可能需要关闭防火墙和win ...

  9. 4组-Alpha冲刺-5/6

    一.基本情况 队名:摸鲨鱼小队 组长博客:https://www.cnblogs.com/smallgrape/p/15563236.html 小组人数:8人 二.冲刺概况汇报 组长:许雅萍 过去两天 ...

  10. uni-app 小程序在iOS系统无法长按复制问题

    最近在使用uni-app开发移动端应用,有客户反映微信小程序版本在使用是无法长按复制问题,在安卓系统上却是正常的. 检查了下代码,对text标签都设置了selectable属性,寻找万能的度娘还是没有 ...