今日题目:

  1. 复杂链表的复制
  2. 二叉搜索树与双向链表
  3. 序列化二叉树
  4. 字符串的排序

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》算法题第七天的更多相关文章

  1. 剑指offer算法题

    数组中只出现一次的数字(一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字): 解法在于位运算中的异或,直接异或可以得到这两个数的异或,按照最后的有效数字位可以 ...

  2. 剑指offer算法总结

    剑指offer算法学习总结 节选剑指offer比较经典和巧妙的一些题目,以便复习使用.一部分题目给出了完整代码,一部分题目比较简单直接给出思路.但是不保证我说的思路都是正确的,个人对算法也不是特别在行 ...

  3. 剑指Offer——算法复杂度中的O(logN)底数是多少

    剑指Offer--算法复杂度中的O(logN)底数是多少 前言 无论是计算机算法概论.还是数据结构书中,关于算法的时间复杂度很多都用包含O(logN)这样的描述,但是却没有明确说logN的底数究竟是多 ...

  4. 剑指 offer 第一题: 二维数组中的查找

    打算写 图解剑指 offer 66 题 的系列文章,不知道大家有没有兴趣

  5. 剑指Offer编程题2——替换空格

    剑指Offer编程题2——替换空格 题目描述 请实现一个函数,将一个字符串中的每个空格替换成“%20”.例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happ ...

  6. 剑指Offer编程题1——二维数组中的查找

    剑指Offer编程题1---------------二维数组中的查找 题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完 ...

  7. 剑指offer编程题66道题 36-66

    36.两个链表的第一个公共节点 题目描述 输入两个链表,找出它们的第一个公共结点. 1.具有重合节点的两个链表是一个Y字性,用两个堆栈放这两个链表,从尾部开始遍历,直到遍历到最后一个重合节点. 这种算 ...

  8. 牛客网剑指offer刷题总结

    二维数组中的查找: 题目描述:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 两 ...

  9. LeetCode剑指Offer刷题总结(一)

    LeetCode过程中值得反思的细节 以下题号均指LeetCode剑指offer题库中的题号 本文章将每周定期更新,当内容达到10题左右时将会开下一节. 二维数组越界问题04 public stati ...

  10. 剑指offer编程题Java实现——面试题11数值的整数次方

    题目: 实现函数double power(double base,int exponent),求base的exponent次方.不得使用库函数,同时不需要考虑大数问题. 解题思路:最一般的方法实现数值 ...

随机推荐

  1. PAT B1036 跟奥巴马一起编程 (15)

    AC代码 #include <cstdio> using namespace std; int main(){ int n = 0, m = 0; char a; scanf(" ...

  2. python 文件写入

    def write_file(): """ 文件写入""" file_name = "wri2te_test.txt" ...

  3. 另类--kafka集群中jmx端口设置

    # 监控kafka集群 # 有一个问题,需要在kafka-server-start.sh文件中配置端口,有如下三种办法 # 第一种:复制并修改kafka目录,比如kafka-1,kafka-2,kaf ...

  4. 05docker仓库---搭建本地仓库

    Docker仓库 仓库(Repository)是集中存放镜像的地方,分别公有仓库和私有仓库. 注册服务器是存放仓库的具体服务器.一个注册服务器上可以有多个仓库,每一个仓库里面可以有多个镜像. eg:仓 ...

  5. spring boot 学习笔记(三)之 配置

    一:概述 在Spring boot 中根据业务需求,我们往往会在不同地方配置我们所需的key-value 配置项,配置文件存在不同的地方的场景如下: (1) 默认存在 application.prop ...

  6. div布局(持续更新)

    1. 效果: 代码: <!DOCTYPE html> <html> <head> <meta name="viewport" conten ...

  7. LeetCode:181.超过经理收入的员工

    题目链接:https://leetcode-cn.com/problems/employees-earning-more-than-their-managers/ 题目 Employee 表包含所有员 ...

  8. 5 java 笔记

    1  建议不要在循环体内修改循环变量的值 2 java语言没有提供goto语句来控制程序的跳转 2 java语言同样也提供了continue和break关键字来控制程序的循环结构 3 java中的标签 ...

  9. 用jquery写出图片自动轮播效果

    相关代码如下,只要把代码粘贴进编辑器,修改图片路径,即可看到效果. 1.html部分 <body>   <ul class="banner">   < ...

  10. DNS缓存失败怎么解决?

    DNS的中文名是域名系统,是域名和IP地址相互映射的一个分布式数据库.有了DNS,我们上网时直接输入网站域名(即网址)即可,而不用输入网站的IP地址访问网站,对于用户来说比较方便记忆和访问. 每次当我 ...