Prefix tree, linked list related topics
trie
- Prefix tree is also named dictionary tree, word lookup tree, Trie tree, multi-channel tree structure, and hash efficiency. It is a multi-tree structure for fast retrieval. It is mostly used for word frequency search or fuzzy query.
- The query is only related to the sample length, not the sample size.
- 1) In a single string, characters from front to back are added to - Multi fork tree
2) Characters are placed on the road, and there are exclusive data items on the node (commonly pass and end values)
3) All samples are added in this way. If there is no road, create a new one, and if there is a road, reuse it
4) The pass value of the node along the way increases by 1, and the end value of the node at the end of each string increases by 1
You can complete prefix related queries
/pic:mw://20f0c6edb22084fc2a039334fc5f7972
pass is the number of passes, and end is the number of times that the current element ends
The cost of building this tree is O (N)
public class Code_01_TrieTree { public static class TrieNode { public int path; public int end; public TrieNode[] nexts; public TrieNode() { path = 0; //How many nodes have arrived end = 0; //How many strings end with this node nexts = new TrieNode[26]; //The path to the child node. If the scope given by the topic is uncertain, use map } } public static class Trie { private TrieNode root; public Trie() { //Prepare a header node root = new TrieNode(); } //Insert a word public void insert(String word) { if (word == null) { return; } char[] chs = word.toCharArray(); TrieNode node = root; int index = 0; for (int i = 0; i < chs.length; i++) { index = chs[i] - 'a'; if (node.nexts[index] == null) { node.nexts[index] = new TrieNode(); } node = node.nexts[index]; node.path++; } node.end++; } //Delete the word from the structure public void delete(String word) { if (search(word) != 0) { char[] chs = word.toCharArray(); TrieNode node = root; int index = 0; for (int i = 0; i < chs.length; i++) { index = chs[i] - 'a'; if (--node.nexts[index].path == 0) { //If a node after - 1 = = 0, it means that the node after this node is also after - 1 = = 0, so directly = null. node.nexts[index] = null; return; } node = node.nexts[index]; } node.end--; } } //Find a word and insert it several times public int search(String word) { if (word == null) { return 0; } char[] chs = word.toCharArray(); TrieNode node = root; int index = 0; for (int i = 0; i < chs.length; i++) { index = chs[i] - 'a'; if (node.nexts[index] == null) { return 0; } node = node.nexts[index]; } return node.end; } //Check the number of prefixes in a string public int prefixNumber(String pre) { if (pre == null) { return 0; } char[] chs = pre.toCharArray(); TrieNode node = root; int index = 0; for (int i = 0; i < chs.length; i++) { index = chs[i] - 'a'; if (node.nexts[index] == null) { return 0; } node = node.nexts[index]; } return node.path; } } public static void main(String[] args) { Trie trie = new Trie(); System.out.println(trie.search("zuo")); trie.insert("zuo"); System.out.println(trie.search("zuo")); trie.delete("zuo"); System.out.println(trie.search("zuo")); trie.insert("zuo"); trie.insert("zuo"); trie.delete("zuo"); System.out.println(trie.search("zuo")); trie.delete("zuo"); System.out.println(trie.search("zuo")); trie.insert("zuoa"); trie.insert("zuoac"); trie.insert("zuoab"); trie.insert("zuoad"); trie.delete("zuoa"); System.out.println(trie.search("zuoa")); System.out.println(trie.prefixNumber("zuo")); } }
Linked list
Written examination can not care about space complexity, all for time complexity
In the interview, time complexity is the most important, but save space
:: speed pointer:
1) Enter the chain header node. The odd length returns the midpoint, and the even length returns the upper midpoint
2) Enter the chain header node. The odd length returns the midpoint, and the even length returns the lower midpoint
3) Enter the chain header node. The odd length returns the previous midpoint, and the even length returns the previous midpoint
4) Enter the chain header node. The odd length returns the one before the midpoint, and the even length returns the one before the next midpoint
1) Enter the chain header node. The odd length returns the midpoint, and the even length returns the upper midpoint
public static Node mid0rUpMidNode(Node head) { if (head = nu11|| head.next == nu11|| head.next.next = nu1l) { return head; } // Node slow = head. next; Node fast = head. next. next; while (fast.next != nu1l && fast.next.next != nu1l) { slow = slow. next; fast = fast .next .next; } return slow; } if (head == null|| head.next == nu1l) { return true; } Node n1 =lhead; Node n2 = head; while (n2.next != nu1l && n2.next.next != nu1l) { // find mid node n1 = n1.next; // n1 ->mid n2 = n2. next.next; 1/ n2 -> end } return n1
2) Enter the chain header node. The odd length returns the midpoint, and the even length returns the lower midpoint
public static Node mid0rDownMidNode (Node head) { if (head == nul1|| head.next = nu1l) { return head; } Node slow = head . next; Node fast = head . next; while (fast.next != nu1l && fast.next.next != nu1l) { slow = slow.next; fast = fast.next .next; } return slow; }
3) Enter the chain header node. The odd length returns the previous midpoint, and the even length returns the previous midpoint
public static Node mid0rUpMidPreNode(Node head) { if (head = nu11|| head.next == nu11|| head.next.next == nu1l) { return nu1l; } Node slow = head; Node fast = head. next. next; while (fast.next != nu1l && fast.next.next != nu11) { slow = slow.next; fast = fast .next .next; } return slow; }
4) Enter the chain header node. The odd length returns the one before the midpoint, and the even length returns the one before the next midpoint
public static Node mi d0rUpMidPreNode(Node head) { if (head = nu11|| head.next == nu11|| head.next.next == nu1l) { return nu1l; } Node slow = head; Node fast = head . next. next; while (fast.next != nu1l && fast.next.next != nu1l) { slow = slow.next; fast = fast .next .next; } return slow; }
:: given the head node of a single linked list, please judge whether the linked list is palindrome structure.::
1) The hash table method is particularly simple (pen trial)
2) The method of changing the original linked list needs to pay attention to the boundary (for interview)
Using the stack, first traverse the stack, then traverse it, and compare it with the elements at the top of the stack
Use less space?
The speed pointer finds the midpoint and the upper midpoint
Press the second half of the stack and compare it with the first half again
Constant space?
First, the speed pointer locates the midpoint and the end, and the next pointer of the midpoint points to null
Reverse the pointers in the second half, and then compare the beginning and end in turn. When one pointer points to null, it is a palindrome structure
If one of them is different, it is a non palindrome
Note that before returning the result, you need to return the second half in reverse order
:: divide the unidirectional linked list into the form of small on the left, equal in the middle and large on the right according to a certain value:
1) Put the linked list into the array and do partition on the array
2) Divided into small, medium and large parts, and then string them together (for interview)
public static Node listPartition2(Node head, int pivot) { Node sH = nu1l; // small head Node sT = nu1l; // small tail Node eH = nu1l; // equal head Node eT = nu1l; // equal tail Node mH = nu11; // big head ! Node mT = nu1l; // big tail Node next = nu1l; // save next node // every node distributed to three lists while (head != nu1l) { next = head.next; head.next = nu1l; if (head.value < pivot) { if (sH == null) { sH = head; sT = head; } else{ sT .next = head; sT = head; }else if (head.value == pivot) { if (eH == nu11) { eH = head; eT = head; } else { eT.next = head; eT = head; } } head= next; } /Xinba in xiaori area, even equal to<The head of the domain, wait for the regional huabalian people to open<Header of domain if (sT != null) { //If there is a small field sT .next = eH; eT= eT==null?sT:eT;//Whoever connects the head larger than the area becomes eT } // The if above, whether it's gone or not, et // all reconnect if (eT != null) { //If it is less than the domain and equal gate < gauge, there is not none eT .next = mH; } returnsH!=null?sH:(eH!=nu1l?eH:mH); }
Copy linked list with special pointer
-A special single linked list node class is described below
class Node {
Int value.
Node next:
Node rand;
Node(int val){ value= val }
}
rand pointer is a new pointer in the node structure of the single linked list. rand may point to any node in the linked list or mull
Given the head node of an acyclic single linked list composed of ndoe node types, please implement a function to copy the linked list and return the head node of the copied new linked list.
[required]
Time complexity ON). Additional space complexity O(1)
/pic:mw://03ccf88fcbe09ad4d166dd62401cea8e
Create map
In the first traversal, key is the old node and value is the new node
Traverse the linked list for the second time, find the new node from the old node, and assign the rand pointer to the new node
Finally, return to the new node
public static Node copyListWi thRand1(Node head) { HashMap<Node, Node> map = new HashMap<Node, Node>(); Node cur = head; while (cur != nu1l) { map.put(cur, new Node(cur .value)); cur = cur .next ; } cur = head; while (cur != nu1l) { .//cur seven // map.get(cur) map.get(cur).next = map. get(cur . next); map. get(cur).rand = map.get(cur.rand); cur = cur .next; } return map. get(head); }
:: copy without hash table:
For the first traversal, create a new node and insert it behind the old node
Set the rand pointer for the second traversal,
If the rand of 1 points to - > 3
Then the copy node of 3 is behind 3
Point the rand pointer of the copy node of 1 to the next node of 3
Finally, the copied nodes are concatenated to return to their head nodes
/pic:mw://ffca72bcc8cf741c73cc9a71ba8edd2b
public static Node copyListWithRand2(Node head) { if (head == nu1l) { return null; } Node cur = head; Node next = null; // copy node and link to every node //1->2 //1-> 1'->2 while (cur != nu11) { //cur old| next = cur .next; cur .next = new Node(cur .value); cur .next.next = next; cur = next; cur = head; } Node curCopy = nu1l; // set copy node rand //1->1'->2->2' while (cur != nu1l) { // cur 2 // cur.next new copy next = cur .next .next; curCopy = cur . next; curCopy.rand = cur .rand != null ? cur.rand.next : null; cur = next; } // head head.next Node res = head.next; . cur = head; // split while (cur != nu1l) { next = cur .next. next; curCopy = cur .next; cur .next = next; curCopy.next = next != nu1l ? next.next : nu11; cur = next; } return res; }
:: return the first node of intersection:
Given two single linked lists that may or may not have rings, the head nodes head1 and head2. Please implement a function. If two linked lists intersect, please return the first node of the intersection. If it does not intersect, null is returned.
[required]
If the sum of the lengths of the two linked lists is N, the time complexity should reach O(N), and the additional space should be complex
The impurity should reach 0 (1).
:: give a linked list with a ring and find out the node into the ring:
//Find the first entry point of the chain leader. If not bad. This is null public static Node getLoopNode(Node head) { if (head == nu11 | head.next == nu11|| head.next.next == nu11) { return nu11; } //n1 fast n2 Node n1 = head.next; // n1 -> slow Node n2 = head.next.next; // n2 -> fast while (n1 != n2) { if (n2.next == null|| n2.next.next == nu1l) { return nu11; } n2 = n2.next .next; n1 = n1.next; } n2 = head; // n2 -> walk again from head while (n1 != n2) { n1 = n1.next; n2 = n2.next; . } return n1; }
Both linked lists are acyclic
All the nodes in the first linked list are entered into the set, and the nodes in the second linked list are found to be overlapping
No set
Traverse the first linked list, record the last node, and record the length of the linked list (the length is recorded as x)
Traverse the second linked list, record the last node, and record the length of the linked list (the length is recorded as y)
If the two last nodes are different, they do not intersect
x and y
Big ones go first, take x-y steps
Then the two linked lists go together and will meet at the intersecting node
//If the two chain lengths are not bad, drive back the parent node of phase: if you don't want disaster. Drive null public static Node noLoop(Node head1, Node head2) { if (head1 == null |I head2 == null) { return nu11; } Node cur1 = head1; Node cur2 = head2; intn=0; while (cur1.next != nu1l) { n++; cur1 = cur1.next; } while (cur2.next != nu1l) { n--; cur2 = cur2.next; } if (cur1 != cur2) { return nu1l; } // n: the value of chain length 1 minus chain length 2 cur1=n>0?headl:head2;//Who grows, whose head becomes cur1 cur2 = cur1 == head1 ? head2 : head1; //Who knows, whose head becomes cur2 while(n1=){ n--; cur1 = cur1.next; while (cur1 != cur2) { cur1 = cur1.next; cur2 = cur2.next; } return cur1; }
One has a ring and the other has no ring. In this case, the two linked lists do not intersect
Both have rings
If two linked lists intersect, they must share this ring
There are three situations
If the memory address of loop1 is equal to the memory address of loop2
Is the second case
If loop 1 is not equal to loop 2
Let loop1 go along the loop. If loop2 is not encountered, it is the first case
That is, there is no intersection
If loop2 is encountered, it is the third case
/pic:mw://6cb42ffbc1d73bb795ceb75c932bc96f
1/Two are linked. Return to network No.Two intersecting nodes. If you don't want to hand in the questions null public static Node bothLoop(Node head1, Node 1oop1, Node head2, Node 1oop2) { Node curl = nu1l; Node cur2 = null; if (loop1 == 1oop2) { cur1 = head1 ; cur2 = head2; intn=0; while (cur1 != 1oop1) { n++; cur1 = cur1.next; } while (cur2 != 1oop2) { n--; cur2 = cur2.next; } cur1=n>0?head1:head2; cur2 = cur1 == head1 ? head2 : head1; n = Math.abs(n); while (n != 0) { n--; cur1 = cur1.next ; } while (cur1 != cur2) { cur1 = cur1.next; cur2 = cur2.next; } }else { cur1 = 1oop1.next; while (cur1 != 1oop1) { if (cur1 == 1oop2) { return loop1; } cur1 = cur1.next; } return nu11; }
Main method
public static Node getIntersectNode (Node head1, Node head2) { if (head1 = null|| head2 = null) { return nu11; Node 1oop1 = getLoopNode(head1); Node_ 1oop2 = getL oopNode (head2) ; if (loop1 == nu11 && loop2 == nu11) { return noloop(head1, head2); } if (loop1 != nu1l && loop2 != nu11) { return bothLoop(head1, loop1, head2, 1oop2); } return null; }
Can you delete this point on the linked list without giving the head node of the single linked list and only the node you want to delete?
Shake smart
Assign the value of the next node of the deleted node to the deleted node, and then point to the next node of the next node
However, the last node cannot be deleted