今日题目:
- 复杂链表的复制
- 二叉搜索树与双向链表
- 序列化二叉树
- 字符串的排序
1.复杂链表的复制
题目描述: 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)思路:这道题比较简单的做法是利用哈希表,把旧节点当成key,把新节点当成value,然后再来建立关系,时间和空间复杂度均为O(n)另外一种做法是将新生成的节点插入旧节点之间,然后再进行提取,时间复杂度为O(n),空间复杂度为O(1)。
代码如下:
1 //利用HashMap
2 public class Solution {
3 public RandomListNode Clone(RandomListNode pHead)
4 {
5 if(pHead == null) return null;
6 Map<RandomListNode, RandomListNode> map = new HashMap<RandomListNode, RandomListNode>();
7 RandomListNode p = pHead;
8 while(p != null){
9 map.put(p,new RandomListNode(p.label));
10 p = p.next;
11 }
12 p = pHead;
13 while(p != null){
14 RandomListNode new_node = map.get(p);
15 if(p.next != null)
16 new_node.next = map.get(p.next);
17 if(p.random != null)
18 new_node.random = map.get(p.random);
19 p = p.next;
20 }
21 return map.get(pHead);
22 }
23 }
24
25
26 //没用到HashMap
27 public class Solution {
28 public RandomListNode Clone(RandomListNode pHead)
29 {
30 if(pHead == null) return null;
31 RandomListNode p = pHead;
32 while(p != null){
33 RandomListNode next = p.next;
34 p.next = new RandomListNode(p.label);
35 p.next.next = next;
36 p = next;
37 }
38
39 p = pHead;
40 while(p != null){
41 if(p.random != null)
42 p.next.random = p.random.next;
43 p = p.next.next;
44 }
45
46 RandomListNode dummy = new RandomListNode(0);
47 RandomListNode q = dummy;
48 p = pHead;
49 while(p != null){
50 RandomListNode tmp = p.next.next;
51 q.next = p.next;
52 q = q.next;
53
54 p.next = tmp;
55
56 p = tmp;
57 }
58
59 return dummy.next;
60 }
61 }
2. 二叉搜索树与双向链表
题目描述: 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。思路:这道题利用二叉搜索树中序遍历序列递增的特性来求解,比较直接。
代码如下:
1 public class Solution {
2 public TreeNode Convert(TreeNode root) {
3 if(root == null) return null;
4 Stack<TreeNode> stack = new Stack();
5 boolean flag = true;
6 TreeNode p = root;
7 TreeNode pre = null;
8 while(p != null || !stack.empty()){
9 if(p != null){
10 stack.push(p);
11 p = p.left;
12 }else{
13 TreeNode node = stack.pop();
14 if(flag){
15 root = node;
16 flag = false;
17 }
18 if(pre != null)
19 pre.right = node;
20 node.left = pre;
21 pre = node;
22 p = node.right;
23 }
24 }
25 return root;
26
27 }
28 }
3. 序列化二叉树
题目描述: 请实现两个函数,分别用来序列化和反序列化二叉树思路:序列化:比较直接,先序遍历二叉树来生成序列反序列化:也是根据先序遍历的思想来做的,但是可能比起序列化来说没那么直观。
代码如下:
1 public class Solution {
2 int index = -1;
3 String Serialize(TreeNode root) {
4 StringBuffer sb = new StringBuffer();
5 if(root == null){
6 sb.append("#,");
7 return sb.toString();
8 }
9 sb.append(root.val+",");
10 sb.append(Serialize(root.left));
11 sb.append(Serialize(root.right));
12 return sb.toString();
13 }
14 TreeNode Deserialize(String str) {
15 index++;
16 int len = str.length();
17 if(index >= len){
18 return null;
19 }
20 String[] strr = str.split(",");
21 TreeNode node = null;
22 if(!strr[index].equals("#")){
23 node = new TreeNode(Integer.valueOf(strr[index]));
24 node.left = Deserialize(str);
25 node.right = Deserialize(str);
26 }
27
28 return node;
29 }
30 }
4. 字符串的排列
题目描述: 输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。思路:回溯法的题目做多了这道题就不是什么难事,唯一要注意的是字符串中的字符有可能是有重复的。参考答案给了另外一种基于交换的解法,比博主自己写的回溯要好得多,下面贴出代码给大家参考。
代码如下:
1 //博主写的回溯法
2 public class Solution {
3 public ArrayList<String> Permutation(String str) {
4 ArrayList<String> res = new ArrayList();
5 if(str.length() == 0) return res;
6 char[] arr = str.toCharArray();
7 Arrays.sort(arr);
8 backtrack(arr,res,new StringBuffer(),new HashSet());
9 return res;
10 }
11
12 public void backtrack(char[] arr,ArrayList<String> res,StringBuffer sb,HashSet<Integer> visited){
13 if(sb.length() == arr.length){
14 res.add(sb.toString());
15 return;
16 }
17 for(int i = 0; i < arr.length; i++){
18 if(visited.contains(i)) continue;
19 sb.append(arr[i]);
20 visited.add(i);
21 backtrack(arr,res,sb,visited);
22 visited.remove(i);
23 sb.deleteCharAt(sb.length()-1);
24 while(i < arr.length-1 && arr[i] == arr[i+1]) i++;
25 }
26 }
27 }
28
29
30 //参考答案给的方法,强烈推荐!!
31 public class Solution {
32 public ArrayList<String> Permutation(String str) {
33 ArrayList<String> res = new ArrayList();
34 if(str.length() == 0) return res;
35 char[] arr = str.toCharArray();
36 backtrack(arr,res,0);
37 Collections.sort(res);
38 return res;
39 }
40
41 public void backtrack(char[] arr,ArrayList<String> res,int ind){
42 if(ind == arr.length-1){
43 res.add(String.valueOf(arr));
44 return;
45 }
46 for(int i = ind; i < arr.length; i++){
47 if(i != ind && arr[i] == arr[ind]) continue;
48 char swap = arr[ind];
49 arr[ind] = arr[i];
50 arr[i] = swap;
51
52 backtrack(arr,res,ind+1);
53
54 swap = arr[ind];
55 arr[ind] = arr[i];
56 arr[i] = swap;
57 }
58 }
59 }
来源:https://www.cnblogs.com/wezheng/p/8409809.html