Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions Topic2_LinkedList/dkhien/01ReverseLinkedList.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Time Complexity: O(n)
// Space Complexity: O(1)

class Solution {
public ListNode reverseList(ListNode head) {
if (head == null) return null;
if (head.next == null) return head;

ListNode newHead = new ListNode();
newHead.next = null;

while (head.next != null) {
// Copy value to current node of the new list
newHead.val = head.val;

// Create the next node
ListNode next = new ListNode();
next.val = head.next.val;

// Connect next node to current node (next -> current) to reverse
next.next = newHead;

// Iterate
newHead = next;
head = head.next;
}

return newHead;
}
}
33 changes: 33 additions & 0 deletions Topic2_LinkedList/dkhien/02MergeTwoSortedLists.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Time Complexity: O(n)
// Space Complexity: O(1)

class Solution {
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
ListNode result = new ListNode();
ListNode current = result;

while (list1 != null && list2 != null) {
// Choose the smaller value to add to the result list
if (list1.val <= list2.val) {
current.next = list1;
list1 = list1.next;
} else {
current.next = list2;
list2 = list2.next;
}

// Iterate
current = current.next;
}

// Add the remaining nodes to the result list
if (list1 != null) {
current.next = list1;
} else if (list2 != null) {
current.next = list2;
}

return result.next;

}
}
37 changes: 37 additions & 0 deletions Topic2_LinkedList/dkhien/03ReorderList.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Time Complexity: O(n)
// Space Complexity: O(n)

class Solution {
public void reorderList(ListNode head) {
List<ListNode> nodeList = new ArrayList<>();
ListNode temp = head;

while (temp != null) {
nodeList.add(temp);
temp = temp.next;
}

// Traverse half of the list
for (int i = 0; i < nodeList.size() / 2; i++) {
ListNode node = nodeList.get(i);

// The next node to link to should have index size - 1 - i
ListNode nextNode = nodeList.get(nodeList.size() - 1 - i);

if (i == nodeList.size() / 2 - 1 && nodeList.size() % 2 == 0) {
// If the list has even number of nodes, the next node of the middle node should be null
nextNode.next = null;
} else if (i == nodeList.size() / 2 - 1 && nodeList.size() % 2 != 0) {
// If the list has odd number of nodes, the next node of the middle node should be the last node
nextNode.next = node.next;
nextNode.next.next = null;
} else {
// Normal case
nextNode.next = node.next;
}

// Link the current node to the next node
node.next = nextNode;
}
}
}
29 changes: 29 additions & 0 deletions Topic2_LinkedList/dkhien/04RemoveNthNodeFromEndOfList.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Time Complexity: O(n)
// Space Complexity: O(1)

class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
if (head == null || head.next == null) return null;
ListNode ptr1 = head;
ListNode ptr2 = head;

// ptr2 starts first, n steps ahead of ptr1
for (int i = 0; i < n; i++) {
if (ptr2.next == null) {
return head.next;
}
ptr2 = ptr2.next;
}

// Move ptr1 and ptr2 until ptr2 reaches the end
while (ptr2.next != null) {
ptr1 = ptr1.next;
ptr2 = ptr2.next;
}

// ptr1 should now be at the (n-1)th node from the end -> remove the next node
ptr1.next = ptr1.next.next;

return head;
}
}
46 changes: 46 additions & 0 deletions Topic2_LinkedList/dkhien/05CopyListWithRandomPointer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Time Complexity: O(n)
// Space Complexity: O(n)

class Solution {
public Node copyRandomList(Node head) {
if (head == null) return null;

// Map original node to its clone
Map<Node, Node> originalToClone = new HashMap<>();
Node res = new Node(0);
Node dummy = res;

// Idea: Clone the list linearly and avoid duplicate cloning by using a map
while (head != null) {
// Clone next node, if in map use the existing clone
Node nextClone;
if (originalToClone.containsKey(head)) {
nextClone = originalToClone.get(head);
} else {
nextClone = new Node(head.val);
originalToClone.put(head, nextClone);
}

dummy.next = nextClone;

// Clone random node, if in map use the existing clone
Node randomClone = null;
if (head.random != null) {
if (originalToClone.containsKey(head.random)) {
randomClone = originalToClone.get(head.random);
} else {
randomClone = new Node(head.random.val);
originalToClone.put(head.random, randomClone);
}
}

dummy.next.random = randomClone;

// Iterate
dummy = nextClone;
head = head.next;
}

return res.next;
}
}
48 changes: 48 additions & 0 deletions Topic2_LinkedList/dkhien/06AddTwoNumbers.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Time Complexity: O(n)
// Space Complexity: O(1)

class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode dummy = new ListNode();
ListNode current = dummy;
int carry = 0;

// Idea: Add each digit like in elementary school
while (true) {

// Calculate the sum of the current digits
// If one of the lists is null, the value of that list is 0
int sum;
if (l1 == null && l2 != null) {
sum = l2.val + carry;
l2 = l2.next;
} else if (l1 != null && l2 == null) {
sum = l1.val + carry;
l1 = l1.next;
} else if (l1 != null && l2 != null) {
sum = l1.val + l2.val + carry;
l1 = l1.next;
l2 = l2.next;
} else {
break;
}

// Calculate the carry and the value of the current digit
carry = sum / 10;
sum %= 10;

// Create a new node and link it to the result list
ListNode res = new ListNode(sum);
current.next = res;
current = res;
}

// Add the last carry if any
if (carry > 0) {
ListNode carryNode = new ListNode(carry);
current.next = carryNode;
}

return dummy.next;
}
}
22 changes: 22 additions & 0 deletions Topic2_LinkedList/dkhien/07LinkedListCycle.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Time Complexity: O(n)
// Space Complexity: O(1)

public class Solution {
public boolean hasCycle(ListNode head) {
if (head == null)
return false;
ListNode slow = head;
ListNode fast = head;

// Idea: The fast pointer will surely meet the slow pointer if there is a cycle
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
if (slow == fast) {
return true;
}
}

return false;
}
}
31 changes: 31 additions & 0 deletions Topic3_StackQueue/dkhien/01ValidParetheses.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Time complexity: O(n)
// Space complexity: O(n)

import java.util.Stack;

class Solution {
public boolean isValid(String s) {
Stack<Character> stack = new Stack<>();

for (char c : s.toCharArray()) {
// If c is an opening bracket, push it to the stack
if (c == '(' || c == '[' || c == '{') {
stack.push(c);
} else {
if (stack.isEmpty()) {
return false;
}
char top = stack.pop();

// If c is a closing bracket, check if it matches the top of the stack
// If not, return false (invalid)
if ((c == ')' && top != '(') || (c == ']' && top != '[') || (c == '}' && top != '{')) {
return false;
}
}
}

// If the stack is empty, the string is valid because all brackets are matched
return stack.isEmpty();
}
}
30 changes: 30 additions & 0 deletions Topic3_StackQueue/dkhien/02MinStack.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Time complexity: O(1) for all operations
// Space complexity: O(n) for the stack

class MinStack {
// Use a pair to store the value and the minimum value at that point
Stack<Pair<Integer, Integer>> stack = new Stack<>();

public void push(int val) {
int min = val;
if (!stack.isEmpty()) {
// Get minimum between the current value and the minimum value of the previous element
min = Math.min(val, stack.peek().getValue());
}

// Push the value and the minimum value to the stack
stack.push(new Pair<>(val, min));
}

public void pop() {
stack.pop();
}

public int top() {
return stack.peek().getKey();
}

public int getMin() {
return stack.peek().getValue();
}
}
36 changes: 36 additions & 0 deletions Topic3_StackQueue/dkhien/03EvaluateReversePolishNotation.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Time complexity: O(n)
// Space complexity: O(n)

class Solution {
public int evalRPN(String[] tokens) {
Stack<Integer> stack = new Stack<>();

for (String token : tokens) {
// If token is an operator, pop 2 operands from the stack and perform the operation
if (token.equals("+") || token.equals("-") || token.equals("*") || token.equals("/")) {
Integer op2 = stack.pop();
Integer op1 = stack.pop();
switch (token) {
case "+":
stack.push(op1 + op2);
break;
case "-":
stack.push(op1 - op2);
break;
case "*":
stack.push(op1 * op2);
break;
case "/":
stack.push(op1 / op2);
break;
}
} else {
// If token is an operand, push it to the stack
stack.push(Integer.parseInt(token));
}
}

// The result is the only element left in the stack
return stack.pop();
}
}
24 changes: 24 additions & 0 deletions Topic3_StackQueue/dkhien/04DailyTemperatures.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Time complexity: O(n)
// Space complexity: O(n)

class Solution {
public int[] dailyTemperatures(int[] temperatures) {
int[] result = new int[temperatures.length];

Stack<Integer> stack = new Stack<>();

for (int i = 0; i < temperatures.length; i++) {
// If the current temperature is higher than the temperature at the top of the stack, then we have found the next warmer temperature.
while (!stack.isEmpty() && temperatures[i] > temperatures[stack.peek()]) {
// Pop the index of the temperature that is lower than the current temperature
int top = stack.pop();
// Calculate the distance between the current temperature and the temperature at the top of the stack
result[top] = i - top;
}
stack.push(i);
}

return result;

}
}
Loading