算法准备-4.14
1.复杂链表的复制
-
描述:请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null
-
思路:分三步,第一步复制每个节点使其位于原节点的后面;第二步建立random指针;第三步恢复链表
-
题解:
/* // Definition for a Node. class Node { int val; Node next; Node random; public Node(int val) { this.val = val; this.next = null; this.random = null; } } */ class Solution { public Node copyRandomList(Node head) { if(head==null) { return null; } copy(head); random(head); return reList(head); } private void copy(Node head){//保证每个节点在原节点的后面 while(head!=null) { Node clonenode=new Node(head.val); Node headnext=head.next; head.next=clonenode; clonenode.next=headnext; head=clonenode.next; } } private void random(Node head){ while(head!=null) { while(head!=null){ Node cloneNode = head.next; if(head.random!=null){ head.next.random = head.random.next; } head = cloneNode.next; } } } private Node reList(Node head) { Node clonehead=head.next; Node clonenode=head.next; head.next=clonenode.next; head=head.next; while(head!=null) { clonenode.next=head.next; head.next=head.next.next; head=head.next; clonenode=clonenode.next; } return clonehead; } }
2. 二叉搜索树转有序双向链表
-
描述:输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的循环双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向
-
思路:首先,因为链表有序,所以我们必须通过中序遍历来访问二叉搜索树,来得到一个有序的访问序列,其次因为他不能创建新的节点,只能改变树中的指针指向,其左指针指向前驱,右指针指向后继,当结束后,再将最后一个节点的后继指针指向head指向的结点。
-
题解:
/* // Definition for a Node. class Node { public int val; public Node left; public Node right; public Node() {} public Node(int _val) { val = _val; } public Node(int _val,Node _left,Node _right) { val = _val; left = _left; right = _right; } }; */ class Solution { Node head,pre;//伪头节点和前驱指针节点 public Node treeToDoublyList(Node root) { if(root==null) { return null; } dfs(root); head.left=pre; pre.right=head; return head; } public void dfs(Node root){//中序遍历二叉搜索树同时改变指针 if(root==null) { return; } dfs(root.left); if(pre!=null) pre.right=root; else head=root;//判断他是否是第一个节点 root.left=pre; pre=root; dfs(root.right); } }
3. 字符串的排列
-
描述:输入一个字符串,打印出该字符串中字符的所有排列
-
思路:此题采用DFS加剪枝,对字符串进行深度优先搜索遍历,要保证同一位置上同意字符只能固定一次,需要建立一个字符数组做对比。
-
题解:
class Solution { List<String> res=new LinkedList<>(); char[] target; public String[] permutation(String s) { target=s.toCharArray(); dfs(0); return res.toArray(new String[res.size()]); } public void dfs(int x){ if(x==target.length-1) { res.add(String.valueOf(target)); return; } HashSet<Character> set = new HashSet<>();//进行重复检验 for(int i=x;i<target.length;i++) { if(set.contains(target[i])) continue; set.add(target[i]); swap(i,x); dfs(x+1); swap(i,x); } } public void swap(int a,int b){ char temp=target[a]; target[a]=target[b]; target[b]=temp; } }
-
反省:这题是参考了leetcode讨论区一位大佬的做法,一开始我不知道这题要用dfs,回溯加剪枝,剪枝时使用的hashset也没用过