Skip to content
Merged
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
310 changes: 155 additions & 155 deletions README.md

Large diffs are not rendered by default.

80 changes: 50 additions & 30 deletions src/main/java/g0001_0100/s0001_two_sum/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,44 +40,64 @@ You can return the answer in any order.

**Follow-up:** Can you come up with an algorithm that is less than <code>O(n<sup>2</sup>)</code> time complexity?

## Solution
To solve the Two Sum problem in Java using a `Solution` class, we'll follow these steps:

1. Define a `Solution` class with a method named `twoSum`.
2. Inside the `twoSum` method, create a hashmap to store elements and their indices.
3. Iterate through the array:
- For each element, calculate the complement required to reach the target sum.
- Check if the complement exists in the hashmap.
- If found, return the indices of the current element and the complement.
- If not found, add the current element and its index to the hashmap.
4. Handle edge cases:
- If no solution is found, return an empty array or null (depending on the problem requirements).

Here's the implementation:

```java
import java.util.HashMap;
import java.util.Map;

public class Solution {
public int[] twoSum(int[] numbers, int target) {
Map<Integer, Integer> indexMap = new HashMap<>();
for (int i = 0; i < numbers.length; i++) {
Integer requiredNum = target - numbers[i];
if (indexMap.containsKey(requiredNum)) {
return new int[] {indexMap.get(requiredNum), i};

public int[] twoSum(int[] nums, int target) {
// Create a hashmap to store elements and their indices
HashMap<Integer, Integer> map = new HashMap<>();

// Iterate through the array
for (int i = 0; i < nums.length; i++) {
int complement = target - nums[i];
// Check if the complement exists in the hashmap
if (map.containsKey(complement)) {
// Return the indices of the current element and the complement
return new int[]{map.get(complement), i};
}
indexMap.put(numbers[i], i);
// Add the current element and its index to the hashmap
map.put(nums[i], i);
}
return new int[] {-1, -1};
// If no solution is found, return an empty array or null
return new int[]{};
}

public static void main(String[] args) {
Solution solution = new Solution();

// Test cases
int[] nums1 = {2, 7, 11, 15};
int target1 = 9;
int[] result1 = solution.twoSum(nums1, target1);
System.out.println("Example 1 Output: [" + result1[0] + ", " + result1[1] + "]");

int[] nums2 = {3, 2, 4};
int target2 = 6;
int[] result2 = solution.twoSum(nums2, target2);
System.out.println("Example 2 Output: [" + result2[0] + ", " + result2[1] + "]");

int[] nums3 = {3, 3};
int target3 = 6;
int[] result3 = solution.twoSum(nums3, target3);
System.out.println("Example 3 Output: [" + result3[0] + ", " + result3[1] + "]");
}
}
```

**Time Complexity (Big O Time):**

The time complexity of this program is O(n), where "n" represents the number of elements in the `numbers` array. Here's the breakdown:

1. The program iterates through the `numbers` array once using a `for` loop, which runs for "n" iterations (n is the length of the array).
2. Inside the loop, it performs constant-time operations:
- It calculates the `requiredNum` (constant time).
- It checks if `requiredNum` is present in the `indexMap` (constant time).
- It puts `numbers[i]` and `i` into the `indexMap` (constant time).

Since all the operations inside the loop are constant time, and the loop itself runs for "n" iterations, the overall time complexity is O(n).

**Space Complexity (Big O Space):**

The space complexity of this program is also O(n), where "n" represents the number of elements in the `numbers` array. Here's why:

1. The program uses a `Map<Integer, Integer>` called `indexMap` to store the numbers and their corresponding indices. In the worst case, it could store all "n" elements from the `numbers` array.
2. The program returns an integer array of size 2 (constant space), regardless of the input size.

The dominant factor in terms of space complexity is the `indexMap`, which can potentially store "n" key-value pairs. Therefore, the space complexity is O(n).
This implementation provides a solution to the Two Sum problem with a time complexity of O(n), where n is the number of elements in the input array.
125 changes: 80 additions & 45 deletions src/main/java/g0001_0100/s0002_add_two_numbers/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,65 +37,100 @@ You may assume the two numbers do not contain any leading zero, except the numbe
* `0 <= Node.val <= 9`
* It is guaranteed that the list represents a number that does not have leading zeros.

## Solution
To solve the Add Two Numbers problem in Java using a `Solution` class, we'll follow these steps:

1. Define a `ListNode` class to represent nodes in a linked list.
2. Define a `Solution` class with a method named `addTwoNumbers`.
3. Inside the `addTwoNumbers` method, traverse both input linked lists simultaneously:
- Keep track of a carry variable to handle cases where the sum of two digits exceeds 9.
- Calculate the sum of the current nodes' values along with the carry.
- Update the carry for the next iteration.
- Create a new node with the sum % 10 and attach it to the result linked list.
- Move to the next nodes in both input lists.
4. After finishing the traversal, check if there is any remaining carry. If so, add a new node with the carry to the result.
5. Return the head of the result linked list.

Here's the implementation:

```java
import com_github_leetcode.ListNode;

/*
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class ListNode {
int val;
ListNode next;

ListNode() {}

ListNode(int val) {
this.val = val;
}

ListNode(int val, ListNode next) {
this.val = val;
this.next = next;
}
}

public class Solution {

public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode dummyHead = new ListNode(0);
ListNode p = l1;
ListNode q = l2;
ListNode dummyHead = new ListNode();
ListNode curr = dummyHead;
int carry = 0;
while (p != null || q != null) {
int x = (p != null) ? p.val : 0;
int y = (q != null) ? q.val : 0;
int sum = carry + x + y;
carry = sum / 10;
curr.next = new ListNode(sum % 10);
curr = curr.next;
if (p != null) {
p = p.next;

while (l1 != null || l2 != null) {
int sum = carry;
if (l1 != null) {
sum += l1.val;
l1 = l1.next;
}
if (q != null) {
q = q.next;
if (l2 != null) {
sum += l2.val;
l2 = l2.next;
}
curr.next = new ListNode(sum % 10);
curr = curr.next;
carry = sum / 10;
}

if (carry > 0) {
curr.next = new ListNode(carry);
}

return dummyHead.next;
}
}
```

**Time Complexity (Big O Time):**

The time complexity of this program is O(max(N, M)), where "N" and "M" represent the lengths of the input linked lists `l1` and `l2`, respectively. Here's the breakdown:

1. The program iterates through both linked lists `l1` and `l2` simultaneously using a `while` loop. The loop runs as long as either of the two lists has elements to process.
2. Inside the loop, it performs constant-time operations for each node:
- It calculates the sum of three integer values (constant time).
- It creates a new node (constant time).
- It updates pointers and variables (constant time).

Since the loop runs until the end of the longer of the two input linked lists, the overall time complexity is O(max(N, M)), where "N" and "M" are the lengths of `l1` and `l2`, respectively.

**Space Complexity (Big O Space):**

The space complexity of this program is O(max(N, M)), which is primarily determined by the space used for the output linked list. Here's why:
// Helper method to print a linked list
public void printList(ListNode head) {
ListNode curr = head;
while (curr != null) {
System.out.print(curr.val + " ");
curr = curr.next;
}
System.out.println();
}

1. The program creates a new linked list to store the result, and the length of this linked list can be at most max(N, M) + 1 (where +1 is for the potential carry at the end).
2. Other than the output linked list, the program uses a constant amount of space for variables like `dummyHead`, `p`, `q`, `curr`, and `carry`.
public static void main(String[] args) {
Solution solution = new Solution();

// Test cases
ListNode l1 = new ListNode(2, new ListNode(4, new ListNode(3)));
ListNode l2 = new ListNode(5, new ListNode(6, new ListNode(4)));
ListNode result1 = solution.addTwoNumbers(l1, l2);
System.out.print("Example 1 Output: ");
solution.printList(result1);

ListNode l3 = new ListNode(0);
ListNode l4 = new ListNode(0);
ListNode result2 = solution.addTwoNumbers(l3, l4);
System.out.print("Example 2 Output: ");
solution.printList(result2);

ListNode l5 = new ListNode(9, new ListNode(9, new ListNode(9, new ListNode(9, new ListNode(9, new ListNode(9, new ListNode(9)))))));
ListNode l6 = new ListNode(9, new ListNode(9, new ListNode(9, new ListNode(9)))));
ListNode result3 = solution.addTwoNumbers(l5, l6);
System.out.print("Example 3 Output: ");
solution.printList(result3);
}
}
```

Therefore, the space complexity is O(max(N, M)).
This implementation provides a solution to the Add Two Numbers problem using linked lists in Java.
Original file line number Diff line number Diff line change
Expand Up @@ -42,54 +42,65 @@ Given a string `s`, find the length of the **longest substring** without repeati
* <code>0 <= s.length <= 5 * 10<sup>4</sup></code>
* `s` consists of English letters, digits, symbols and spaces.

## Solution
To solve the Longest Substring Without Repeating Characters problem in Java using a `Solution` class, we'll follow these steps:

1. Define a `Solution` class with a method named `lengthOfLongestSubstring`.
2. Initialize variables to keep track of the starting index of the substring (`start`), the maximum length (`maxLen`), and a hashmap to store characters and their indices.
3. Iterate through the string `s`, and for each character:
- Check if the character exists in the hashmap and its index is greater than or equal to the `start` index.
- If found, update the `start` index to the index after the last occurrence of the character.
- Update the maximum length if necessary.
- Update the index of the current character in the hashmap.
4. Return the maximum length found.
5. Handle the edge case where the input string is empty.

Here's the implementation:

```java
import java.util.HashMap;

public class Solution {

public int lengthOfLongestSubstring(String s) {
int[] lastIndices = new int[256];
for (int i = 0; i < 256; i++) {
lastIndices[i] = -1;
}
int maxLen = 0;
int curLen = 0;
// Initialize variables
int start = 0;
for (int i = 0; i < s.length(); i++) {
char cur = s.charAt(i);
if (lastIndices[cur] < start) {
lastIndices[cur] = i;
curLen++;
} else {
int lastIndex = lastIndices[cur];
start = lastIndex + 1;
curLen = i - start + 1;
lastIndices[cur] = i;
}
if (curLen > maxLen) {
maxLen = curLen;
int maxLen = 0;
HashMap<Character, Integer> map = new HashMap<>();

// Iterate through the string
for (int end = 0; end < s.length(); end++) {
char ch = s.charAt(end);
// If the character exists in the hashmap and its index is greater than or equal to the start index
if (map.containsKey(ch) && map.get(ch) >= start) {
// Update the start index to the index after the last occurrence of the character
start = map.get(ch) + 1;
}
// Update the maximum length if necessary
maxLen = Math.max(maxLen, end - start + 1);
// Update the index of the current character in the hashmap
map.put(ch, end);
}

return maxLen;
}
}
```

**Time Complexity (Big O Time):**

The time complexity of this program is O(n), where "n" represents the length of the input string `s`. Here's the breakdown:

1. The program iterates through the characters of the input string `s` using a `for` loop, and this loop runs for "n" iterations, where "n" is the length of `s`.
2. Inside the loop, it performs constant-time operations:
- Initializing the `lastIndices` array (constant time).
- Updating values in the `lastIndices` array (constant time).
- Updating variables like `maxLen`, `curLen`, `start`, and `lastIndices[cur]` (constant time).
public static void main(String[] args) {
Solution solution = new Solution();

Since the loop runs for "n" iterations, and all operations inside the loop are constant time, the overall time complexity is O(n).
// Test cases
String s1 = "abcabcbb";
System.out.println("Example 1 Output: " + solution.lengthOfLongestSubstring(s1));

**Space Complexity (Big O Space):**
String s2 = "bbbbb";
System.out.println("Example 2 Output: " + solution.lengthOfLongestSubstring(s2));

The space complexity of this program is O(256) = O(1), as it uses a fixed-size array `lastIndices` of length 256 to store the last indices of characters. This array's size does not depend on the input size and remains constant.
String s3 = "pwwkew";
System.out.println("Example 3 Output: " + solution.lengthOfLongestSubstring(s3));

Additionally, the program uses a few integer variables and constant space to store the result. The space used for these variables does not depend on the input size and is also considered constant.
String s4 = "";
System.out.println("Example 4 Output: " + solution.lengthOfLongestSubstring(s4));
}
}
```

Therefore, the space complexity is O(1), or more precisely, O(256), which is still considered constant because it doesn't grow with the input size.
This implementation provides a solution to the Longest Substring Without Repeating Characters problem in Java.
Loading