今日题目:

  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. DP大大大大大赏

    还是前置: 动态规划的三种实现方法: 递推,递归,记忆化搜索 然后还是从斐波那契数列开始引入: 两种求斐波那契数列的方法: 1.用其他位置的结果得到自己的结果: 2.用自己的结果算其他的结果: 以上两 ...

  2. GCD and LCM HDU - 4497(质因数分解)

    Problem Description Given two positive integers G and L, could you tell me how many solutions of (x, ...

  3. PAT A1025 PAT Ranking(25)

    题目描述 Programming Ability Test (PAT) is organized by the College of Computer Science and Technology o ...

  4. django时区与时间差的问题

    时区的正确配置方式: # 这里还可以配置成中文 一般用不到 LANGUAGE_CODE = 'en-us' # TIME_ZONE = 'UTC' TIME_ZONE = 'Asia/Shanghai ...

  5. Android 直连SQL

    在工作中遇到需求需要Android直接连接SQL,看了一些人说不建议直连,但我对性能没有要求,甚至说只要在局域网内能够使用就行,简单说把手机当作一个简单的移动操作点. 代码的话,网上都有比如: htt ...

  6. API接口利用ActionFilterAttribute实现接口耗时检测

    1.主要代码 using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; ...

  7. java.sql.SQLException: Could not retrieve transaction read-only status from server 问题解决

    网上有2种主要说法 第一种 问题描述: java代码在开始事务后,先做了一个查询,再insert,此时会报:          java.sql.SQLException: could not ret ...

  8. php 获取网址参数

    echo "rewrite: ".$_GET["rewrite"]; echo "<br>SERVER_PORT: ".$_SE ...

  9. 什么是PAM认证

    PAM(Pluggable Authentication Modules )是由 Sun 提出的一种用于实现应用程序的认证机制.其核心是一套共享库,目的是提供一个框架和一套编程接口,将认证工作由程序员 ...

  10. 解决myeclipse没有代码提示的问题

    今天和室友安装了一样的myeclipse版本,结果室友的自动提示功能有,我的输入“.”后却不能提示,这对我们敲代码简直来说是一个折磨,不能自动提示,本来还以为是系统问题,一个是win7,一个是win1 ...