Skip to content

Commit e54053b

Browse files
author
FreeTymeKiyan
committed
add Sliding window maximum, Count Univalue Subtrees, Group Shifted Strings
1 parent 1918788 commit e54053b

15 files changed

+700
-490
lines changed
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package com.freetymekiyan.algorithms.level.easy;
2+
3+
import com.freetymekiyan.algorithms.utils.Utils.TreeNode;
4+
5+
/**
6+
* 235. Lowest Common Ancestor of a Binary Search Tree
7+
* <p>
8+
* Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BST.
9+
* <p>
10+
* According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes v and w as
11+
* the lowest node in T that has both v and w as descendants (where we allow a node to be a descendant of itself).”
12+
* |
13+
* | _______6______
14+
* | / \
15+
* | ___2__ ___8__
16+
* | / \ / \
17+
* | 0 _4 7 9
18+
* | / \
19+
* | 3 5
20+
* |
21+
* For example, the lowest common ancestor (LCA) of nodes 2 and 8 is 6.
22+
* <p>
23+
* Another example is LCA of nodes 2 and 4 is 2, since a node can be a descendant of itself according to the LCA
24+
* definition.
25+
* <p>
26+
* Company Tags: Amazon, Microsoft, Facebook, Twitter
27+
* Tags: Tree
28+
* Similar Problems: (M) Lowest Common Ancestor of a Binary Tree
29+
*/
30+
public class LowestCommonAncestorOfABinarySearchTree {
31+
32+
/**
33+
* Iterative.
34+
* In BST, the lca's value can only be [p, q].
35+
* And lca is the first from top to bottom that lies in range.
36+
* If the value is less than both p and q's values, move to right subtree.
37+
* If the value is more than both p and q's values, move to left subtree.
38+
* If the value is in between the two nodes, return the node.
39+
* Otherwise there is no LCA.
40+
*/
41+
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
42+
while (root != null) {
43+
if (root.val < p.val && root.val < q.val) {
44+
root = root.right;
45+
} else if (root.val > p.val && root.val > q.val) {
46+
root = root.left;
47+
} else {
48+
return root;
49+
}
50+
}
51+
return null; // Reach null and lca not found.
52+
}
53+
54+
/**
55+
* Recursion.
56+
* LCA's value must be between [p, q].
57+
* Recurrent relation:
58+
* If root's value < p's and q's, LCA is in the right subtree.
59+
* If root's value > p's and q's, LCA is in the left subtree.
60+
* Else, root's value in between, LCA is root.
61+
* Base case:
62+
* If root is null, return null.
63+
* Complete task:
64+
* Deal with base case. Search left, search right. Return result.
65+
*/
66+
public TreeNode lowestCommonAncestorB(TreeNode root, TreeNode p, TreeNode q) {
67+
if (root == null) {
68+
return null;
69+
}
70+
if (root.val < p.val && root.val < q.val) {
71+
return lowestCommonAncestorB(root.right, p, q);
72+
} else if (root.val > p.val && root.val > q.val) {
73+
return lowestCommonAncestorB(root.left, p, q);
74+
}
75+
return root; // root's value in between p and q.
76+
}
77+
}

src/main/java/com/freetymekiyan/algorithms/level/easy/LowestCommonAncestorOfBST.java

Lines changed: 0 additions & 77 deletions
This file was deleted.

src/main/java/com/freetymekiyan/algorithms/level/easy/PalindromeLinkedList.java

Lines changed: 53 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -16,60 +16,60 @@
1616
*/
1717
public class PalindromeLinkedList {
1818

19-
/**
20-
* Two Pointers.
21-
* Find the middle node, reverse the right half list, then check each node.
22-
* Use two pointers, one slow pointer s, one fast pointer f.
23-
* Move s to the head of the right half list.
24-
* If there are odd number of nodes, move s one step further.
25-
* Reverse the right half of the list starting from s.
26-
* Then compare each node's value while s is not null.
27-
* If diff, return false. Else continue.
28-
* After all nodes checked, return true.
29-
*/
30-
public boolean isPalindrome(ListNode head) {
31-
if (head == null || head.next == null) {
32-
return true;
33-
}
34-
ListNode slow = head;
35-
ListNode fast = head;
36-
while (fast != null && fast.next != null) {
37-
slow = slow.next;
38-
fast = fast.next.next;
39-
}
40-
if (fast != null) { // Odd # of nodes. Make sure slow is always the head of right half.
41-
slow = slow.next;
42-
}
43-
slow = reverseList(slow); // Reverse the right half of the list.
44-
ListNode cur = head;
45-
while (slow != null) { // Slow can reach tail early.
46-
if (cur.val != slow.val) {
47-
return false;
48-
}
49-
cur = cur.next;
50-
slow = slow.next;
51-
}
52-
return true;
19+
/**
20+
* Two Pointers.
21+
* Find the middle node, reverse the right half list, then check each node.
22+
* Use two pointers, one slow pointer s, one fast pointer f.
23+
* Move s to the head of the right half list.
24+
* If there are odd number of nodes, move s one step further.
25+
* Reverse the right half of the list starting from s.
26+
* Then compare each node's value while s is not null.
27+
* If diff, return false. Else continue.
28+
* After all nodes checked, return true.
29+
*/
30+
public boolean isPalindrome(ListNode head) {
31+
if (head == null || head.next == null) {
32+
return true;
5333
}
34+
ListNode slow = head;
35+
ListNode fast = head;
36+
while (fast != null && fast.next != null) {
37+
slow = slow.next;
38+
fast = fast.next.next;
39+
}
40+
if (fast != null) { // Odd # of nodes. Make sure slow is always the head of right half.
41+
slow = slow.next;
42+
}
43+
slow = reverseList(slow); // Reverse the right half of the list.
44+
ListNode cur = head;
45+
while (slow != null) { // Slow can reach tail early.
46+
if (cur.val != slow.val) {
47+
return false;
48+
}
49+
cur = cur.next;
50+
slow = slow.next;
51+
}
52+
return true;
53+
}
5454

55-
/**
56-
* Iterative.
57-
* Create a new head as null, which will be the tail of the reversed list.
58-
* While head is not null:
59-
* | Store the next node.
60-
* | Reverse head.
61-
* | Update new head.
62-
* | Move to next.
63-
* Return new head.
64-
*/
65-
private ListNode reverseList(ListNode head) {
66-
ListNode newHead = null;
67-
while (head != null) {
68-
ListNode next = head.next;
69-
head.next = newHead;
70-
newHead = head;
71-
head = next;
72-
}
73-
return newHead;
55+
/**
56+
* Iterative.
57+
* Create a new head as null, which will be the tail of the reversed list.
58+
* While head is not null:
59+
* | Store the next node.
60+
* | Reverse head.
61+
* | Update new head.
62+
* | Move to next.
63+
* Return new head.
64+
*/
65+
private ListNode reverseList(ListNode head) {
66+
ListNode newHead = null;
67+
while (head != null) {
68+
ListNode next = head.next;
69+
head.next = newHead;
70+
newHead = head;
71+
head = next;
7472
}
73+
return newHead;
74+
}
7575
}
Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,28 @@
11
package com.freetymekiyan.algorithms.level.easy;
22

33
/**
4+
* 231. Power of Two
5+
* <p>
46
* Given an integer, write a function to determine if it is a power of two.
57
* <p>
68
* Tags: Math, Bit Manipulation
79
* Similar Problems: (E) Number of 1 Bits, (E) Power of Three, (E) Power of Four
810
*/
911
public class PowerOfTwo {
1012

11-
/**
12-
* 2's power only has a single 1 at the highest bit.
13-
* So n & (n - 1) should be 0.
14-
* Check also if n is positive.
15-
*/
16-
public boolean isPowerOfTwo(int n) {
17-
return n > 0 && (n & (n - 1)) == 0;
18-
}
13+
/**
14+
* 2's power only has a single 1 at the highest bit.
15+
* So n & (n - 1) should be 0.
16+
* Check also if n is positive.
17+
*/
18+
public boolean isPowerOfTwo(int n) {
19+
return n > 0 && (n & (n - 1)) == 0;
20+
}
1921

20-
/**
21-
* One-liner using Integer.bitCount because only a single bit should be 1 for 2's power.
22-
*/
23-
public boolean isPowerOfTwoB(int n) {
24-
return n > 0 && Integer.bitCount(n) == 1;
25-
}
22+
/**
23+
* One-liner using Integer.bitCount because only a single bit should be 1 for 2's power.
24+
*/
25+
public boolean isPowerOfTwoB(int n) {
26+
return n > 0 && Integer.bitCount(n) == 1;
27+
}
2628
}

src/main/java/com/freetymekiyan/algorithms/level/easy/StrobogrammaticNumber.java

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -15,27 +15,27 @@
1515
*/
1616
public class StrobogrammaticNumber {
1717

18-
/**
19-
* Math.
20-
* Take a look at all digits from 0 to 9.
21-
* 0,1,8 are strobogrammatic no matter what.
22-
* 6 and 9 can form a strobogrammatic pair, which means they must be center symmetrical.
23-
* Other digits just cannot be strobogrammatic.
24-
*/
25-
public boolean isStrobogrammatic(String num) {
26-
int len = num.length() / 2;
27-
for (int i = 0; i < len; i++) {
28-
char d = num.charAt(i);
29-
if (d == '0' || d == '1' || d == '8') {
30-
continue;
31-
} else if (d == '6') {
32-
if (num.charAt(num.length() - 1 - i) != '9') return false;
33-
} else if (d == '9') {
34-
if (num.charAt(num.length() - 1 - i) != '6') return false;
35-
} else {
36-
return false;
37-
}
38-
}
39-
return true;
18+
/**
19+
* Math.
20+
* Take a look at all digits from 0 to 9.
21+
* 0,1,8 are strobogrammatic no matter what.
22+
* 6 and 9 can form a strobogrammatic pair, which means they must be center symmetrical.
23+
* Other digits just cannot be strobogrammatic.
24+
*/
25+
public boolean isStrobogrammatic(String num) {
26+
int len = num.length() / 2;
27+
for (int i = 0; i < len; i++) {
28+
char d = num.charAt(i);
29+
if (d == '0' || d == '1' || d == '8') {
30+
continue;
31+
} else if (d == '6') {
32+
if (num.charAt(num.length() - 1 - i) != '9') return false;
33+
} else if (d == '9') {
34+
if (num.charAt(num.length() - 1 - i) != '6') return false;
35+
} else {
36+
return false;
37+
}
4038
}
39+
return true;
40+
}
4141
}

0 commit comments

Comments
 (0)