《剑指offer》算法题第七天
今日题目:
- 复杂链表的复制
- 二叉搜索树与双向链表
- 序列化二叉树
- 字符串的排序
1.复杂链表的复制
题目描述:
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空) 思路:
这道题比较简单的做法是利用哈希表,把旧节点当成key,把新节点当成value,然后再来建立关系,时间和空间复杂度均为O(n)
另外一种做法是将新生成的节点插入旧节点之间,然后再进行提取,时间复杂度为O(n),空间复杂度为O(1)。
代码如下:
//利用HashMap
public class Solution {
public RandomListNode Clone(RandomListNode pHead)
{
if(pHead == null) return null;
Map<RandomListNode, RandomListNode> map = new HashMap<RandomListNode, RandomListNode>();
RandomListNode p = pHead;
while(p != null){
map.put(p,new RandomListNode(p.label));
p = p.next;
}
p = pHead;
while(p != null){
RandomListNode new_node = map.get(p);
if(p.next != null)
new_node.next = map.get(p.next);
if(p.random != null)
new_node.random = map.get(p.random);
p = p.next;
}
return map.get(pHead);
}
} //没用到HashMap
public class Solution {
public RandomListNode Clone(RandomListNode pHead)
{
if(pHead == null) return null;
RandomListNode p = pHead;
while(p != null){
RandomListNode next = p.next;
p.next = new RandomListNode(p.label);
p.next.next = next;
p = next;
} p = pHead;
while(p != null){
if(p.random != null)
p.next.random = p.random.next;
p = p.next.next;
} RandomListNode dummy = new RandomListNode(0);
RandomListNode q = dummy;
p = pHead;
while(p != null){
RandomListNode tmp = p.next.next;
q.next = p.next;
q = q.next; p.next = tmp; p = tmp;
} return dummy.next;
}
}
2. 二叉搜索树与双向链表
题目描述:
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。 思路:
这道题利用二叉搜索树中序遍历序列递增的特性来求解,比较直接。
代码如下:
public class Solution {
public TreeNode Convert(TreeNode root) {
if(root == null) return null;
Stack<TreeNode> stack = new Stack();
boolean flag = true;
TreeNode p = root;
TreeNode pre = null;
while(p != null || !stack.empty()){
if(p != null){
stack.push(p);
p = p.left;
}else{
TreeNode node = stack.pop();
if(flag){
root = node;
flag = false;
}
if(pre != null)
pre.right = node;
node.left = pre;
pre = node;
p = node.right;
}
}
return root; }
}
3. 序列化二叉树
题目描述:
请实现两个函数,分别用来序列化和反序列化二叉树 思路:
序列化:比较直接,先序遍历二叉树来生成序列
反序列化:也是根据先序遍历的思想来做的,但是可能比起序列化来说没那么直观。
代码如下:
public class Solution {
int index = -1;
String Serialize(TreeNode root) {
StringBuffer sb = new StringBuffer();
if(root == null){
sb.append("#,");
return sb.toString();
}
sb.append(root.val+",");
sb.append(Serialize(root.left));
sb.append(Serialize(root.right));
return sb.toString();
}
TreeNode Deserialize(String str) {
index++;
int len = str.length();
if(index >= len){
return null;
}
String[] strr = str.split(",");
TreeNode node = null;
if(!strr[index].equals("#")){
node = new TreeNode(Integer.valueOf(strr[index]));
node.left = Deserialize(str);
node.right = Deserialize(str);
} return node;
}
}
4. 字符串的排列
题目描述:
输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。 思路:
回溯法的题目做多了这道题就不是什么难事,唯一要注意的是字符串中的字符有可能是有重复的。
参考答案给了另外一种基于交换的解法,比博主自己写的回溯要好得多,下面贴出代码给大家参考。
代码如下:
//博主写的回溯法
public class Solution {
public ArrayList<String> Permutation(String str) {
ArrayList<String> res = new ArrayList();
if(str.length() == 0) return res;
char[] arr = str.toCharArray();
Arrays.sort(arr);
backtrack(arr,res,new StringBuffer(),new HashSet());
return res;
} public void backtrack(char[] arr,ArrayList<String> res,StringBuffer sb,HashSet<Integer> visited){
if(sb.length() == arr.length){
res.add(sb.toString());
return;
}
for(int i = 0; i < arr.length; i++){
if(visited.contains(i)) continue;
sb.append(arr[i]);
visited.add(i);
backtrack(arr,res,sb,visited);
visited.remove(i);
sb.deleteCharAt(sb.length()-1);
while(i < arr.length-1 && arr[i] == arr[i+1]) i++;
}
}
} //参考答案给的方法,强烈推荐!!
public class Solution {
public ArrayList<String> Permutation(String str) {
ArrayList<String> res = new ArrayList();
if(str.length() == 0) return res;
char[] arr = str.toCharArray();
backtrack(arr,res,0);
Collections.sort(res);
return res;
} public void backtrack(char[] arr,ArrayList<String> res,int ind){
if(ind == arr.length-1){
res.add(String.valueOf(arr));
return;
}
for(int i = ind; i < arr.length; i++){
if(i != ind && arr[i] == arr[ind]) continue;
char swap = arr[ind];
arr[ind] = arr[i];
arr[i] = swap; backtrack(arr,res,ind+1); swap = arr[ind];
arr[ind] = arr[i];
arr[i] = swap;
}
}
}
《剑指offer》算法题第七天的更多相关文章
- 剑指offer算法题
数组中只出现一次的数字(一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字): 解法在于位运算中的异或,直接异或可以得到这两个数的异或,按照最后的有效数字位可以 ...
- 剑指offer算法总结
剑指offer算法学习总结 节选剑指offer比较经典和巧妙的一些题目,以便复习使用.一部分题目给出了完整代码,一部分题目比较简单直接给出思路.但是不保证我说的思路都是正确的,个人对算法也不是特别在行 ...
- 剑指Offer——算法复杂度中的O(logN)底数是多少
剑指Offer--算法复杂度中的O(logN)底数是多少 前言 无论是计算机算法概论.还是数据结构书中,关于算法的时间复杂度很多都用包含O(logN)这样的描述,但是却没有明确说logN的底数究竟是多 ...
- 剑指 offer 第一题: 二维数组中的查找
打算写 图解剑指 offer 66 题 的系列文章,不知道大家有没有兴趣
- 剑指Offer编程题2——替换空格
剑指Offer编程题2——替换空格 题目描述 请实现一个函数,将一个字符串中的每个空格替换成“%20”.例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happ ...
- 剑指Offer编程题1——二维数组中的查找
剑指Offer编程题1---------------二维数组中的查找 题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完 ...
- 剑指offer编程题66道题 36-66
36.两个链表的第一个公共节点 题目描述 输入两个链表,找出它们的第一个公共结点. 1.具有重合节点的两个链表是一个Y字性,用两个堆栈放这两个链表,从尾部开始遍历,直到遍历到最后一个重合节点. 这种算 ...
- 牛客网剑指offer刷题总结
二维数组中的查找: 题目描述:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 两 ...
- LeetCode剑指Offer刷题总结(一)
LeetCode过程中值得反思的细节 以下题号均指LeetCode剑指offer题库中的题号 本文章将每周定期更新,当内容达到10题左右时将会开下一节. 二维数组越界问题04 public stati ...
- 剑指offer编程题Java实现——面试题11数值的整数次方
题目: 实现函数double power(double base,int exponent),求base的exponent次方.不得使用库函数,同时不需要考虑大数问题. 解题思路:最一般的方法实现数值 ...
随机推荐
- PAT A1025 PAT Ranking(25)
题目描述 Programming Ability Test (PAT) is organized by the College of Computer Science and Technology o ...
- PAT B1027 打印沙漏(20)
思路: 使用数组保存每一行沙漏的最大符号数 输入一个正整数和一个符号 遍历数组,找到大于正整数的数组下标 j. 三角形底边的字符数为 (j - 1) * 2 - 1 打印沙漏 打印剩余字符:x - n ...
- T100——英文版凭证报表
范例:cxrr001 效果:增加英文版报表选择 1.azzi301,复制cxrr001_g01,把样板编号改为cxrr001_g01_01: 2.下载cxrr001_g01的GR样板,把cxrr001 ...
- python函数篇0-2
函数的有三中不同的参数: 普通参数 默认参数 动态参数# ######### 定义函数 ######### # name 叫做函数func的形式参数,简称:形参def func(name): p ...
- 解决VS2005打开js,css,asp.php等文件,中文都是乱码的问题
用记事本打开可以正常观看但是用VS2005编辑器打开JS,中文确实乱码. 解决办法:在VS 2005 的设置里面选择自动检测Utf-8:“工具”->“选项”->“文本编辑器”->“自 ...
- 12 Mysql之工作中常用操作
Mysql 专题讲解 一.用户创建与权限管理 a) 创建和删除用户 创建用户: CREATE USER jack@localhost; UPDATE USER SET password=passwo ...
- IntelliJ IDEA(Community版本)本地模式的下载、安装及其使用
对于初学者来说可以先使用免费的社区版本练练手. ideaIC-2017.3.5——>社区版 ideaIU-2017.3.5——>旗舰版 一.IntelliJ IDEA(Community版 ...
- span 如何移除点击事件
//设置点击事件不可用 $("#verificode").css("pointer-events", "none"); //倒计时完毕,点击 ...
- 查看磁盘空间,Android各目录讲解
dfFilesystem Size Used Free Blksize/dev 2.0G 116.0K 2.0G 4096----------包含了所有Linux系统中使用的外部设备/sys/fs/c ...
- 使用wget下载百度云资源
目录 使用wget下载百度云资源 一.材料准备: 二.步骤 三.总结 使用wget下载百度云资源 一.材料准备: [BaiduPan explorer]谷歌插件,可以加载文件的真实下载地址 [Chro ...