Skip to content

Commit f831832

Browse files
authored
Merge pull request ByteByteGoHq#26 from Jer3myYu/java-solutions-sort-and-search
Java Chapter 17: Sort and Search
2 parents 3f4f2a2 + 432b570 commit f831832

7 files changed

+268
-0
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
public class DutchNationalFlag {
2+
public void dutchNationalFlag(int[] nums) {
3+
int i = 0;
4+
int left = 0;
5+
int right = nums.length - 1;
6+
while (i <= right) {
7+
// Swap 0s with the element at the left pointer.
8+
if (nums[i] == 0) {
9+
swap(nums, i, left);
10+
left++;
11+
i++;
12+
}
13+
// Swap 2s with the element at the right pointer.
14+
else if (nums[i] == 2) {
15+
swap(nums, i, right);
16+
right--;
17+
} else {
18+
i++;
19+
}
20+
}
21+
}
22+
23+
private void swap(int[] nums, int a, int b) {
24+
int tmp = nums[a];
25+
nums[a] = nums[b];
26+
nums[b] = tmp;
27+
}
28+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import java.util.PriorityQueue;
2+
3+
public class KthLargestIntegerMinHeap {
4+
public int kthLargestIntegerMinHeap(int[] nums, int k) {
5+
PriorityQueue<Integer> minHeap = new PriorityQueue<>();
6+
for (int num : nums) {
7+
// Ensure the heap has at least 'k' integers.
8+
if (minHeap.size() < k) {
9+
minHeap.offer(num);
10+
}
11+
// If 'num' is greater than the smallest integer in the heap, pop
12+
// off this smallest integer from the heap and push in 'num'.
13+
else if (num > minHeap.peek()) {
14+
minHeap.poll();
15+
minHeap.offer(num);
16+
}
17+
}
18+
return minHeap.peek();
19+
}
20+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
public class KthLargestIntegerQuickselect {
2+
public int kthLargestIntegerQuickselect(int[] nums, int k) {
3+
return quickselect(nums, 0, nums.length - 1, k);
4+
}
5+
6+
private int quickselect(int[] nums, int left, int right, int k) {
7+
int n = nums.length;
8+
if (left >= right) return nums[left];
9+
int randomIndex = left + (int)(Math.random() * (right - left + 1));
10+
swap(nums, randomIndex, right);
11+
int pivotIndex = partition(nums, left, right);
12+
// If the pivot comes before 'n - k', the ('n - k')th smallest
13+
// integer is somewhere to its right. Perform quickselect on the
14+
// right part.
15+
if (pivotIndex < n - k) return quickselect(nums, pivotIndex + 1, right, k);
16+
// If the pivot comes after 'n - k', the ('n - k')th smallest integer
17+
// is somewhere to its left. Perform quickselect on the left part.
18+
else if (pivotIndex > n - k) return quickselect(nums, left, pivotIndex - 1, k);
19+
// If the pivot is at index 'n - k', it's the ('n - k')th smallest
20+
// integer.
21+
else return nums[pivotIndex];
22+
}
23+
24+
private int partition(int[] nums, int left, int right) {
25+
int pivot = nums[right];
26+
int lo = left;
27+
for (int i = left; i < right; i++) {
28+
if (nums[i] < pivot) {
29+
swap(nums, lo, i);
30+
lo++;
31+
}
32+
}
33+
swap(nums, lo, right);
34+
return lo;
35+
}
36+
37+
private void swap(int[] nums, int a, int b) {
38+
int tmp = nums[a];
39+
nums[a] = nums[b];
40+
nums[b] = tmp;
41+
}
42+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import java.util.Arrays;
2+
3+
public class SortArrayCountingSort {
4+
public int[] sortArrayCountingSort(int[] nums) {
5+
if (nums == null || nums.length == 0) return nums;
6+
int[] res = new int[nums.length];
7+
int max = Arrays.stream(nums).max().getAsInt();
8+
// Count occurrences of each element in 'nums'.
9+
int[] counts = new int[max + 1];
10+
for (int num : nums) {
11+
counts[num]++;
12+
}
13+
// Build the sorted array by appending each index 'i' to it a total
14+
// of 'counts[i]' times.
15+
int idx = 0;
16+
for (int i = 0; i < counts.length; i++) {
17+
for (int j = 0; j < counts[i]; j++) {
18+
res[idx] = i;
19+
idx++;
20+
}
21+
}
22+
return res;
23+
}
24+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
public class SortArrayQuicksort {
2+
public int[] sortArray(int[] nums) {
3+
quicksort(nums, 0, nums.length - 1);
4+
return nums;
5+
}
6+
7+
private void quicksort(int[] nums, int left, int right) {
8+
// Base case: if the subarray has 0 or 1 element, it's already
9+
// sorted.
10+
if (left >= right) return;
11+
// Partition the array and retrieve the pivot index.
12+
int pivotIndex = partition(nums, left, right);
13+
// Call quicksort on the left and right parts to recursively sort
14+
// them.
15+
quicksort(nums, left, pivotIndex - 1);
16+
quicksort(nums, pivotIndex + 1, right);
17+
}
18+
19+
private int partition(int[] nums, int left, int right) {
20+
int pivot = nums[right];
21+
int lo = left;
22+
// Move all numbers less than the pivot to the left, which
23+
// consequently positions all numbers greater than or equal to the
24+
// pivot to the right.
25+
for (int i = left; i < right; i++) {
26+
if (nums[i] < pivot) {
27+
swap(nums, lo, i);
28+
lo++;
29+
}
30+
}
31+
// After partitioning, 'lo' will be positioned where the pivot should
32+
// be. So, swap the pivot number with the number at the 'lo' pointer.
33+
swap(nums, lo, right);
34+
return lo;
35+
}
36+
37+
private void swap(int[] nums, int a, int b) {
38+
int tmp = nums[a];
39+
nums[a] = nums[b];
40+
nums[b] = tmp;
41+
}
42+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
public class SortArrayQuicksortOptimized {
2+
public int[] sortArray(int[] nums) {
3+
quicksortOptimized(nums, 0, nums.length - 1);
4+
return nums;
5+
}
6+
7+
private void quicksortOptimized(int[] nums, int left, int right) {
8+
if (left >= right) return;
9+
// Choose a pivot at a random index.
10+
// Math.random() generate a double in [0.0, 1.0)
11+
// Scale the range from [0.0, 1.0) to [0, right - left + 1)
12+
int randomIndex = left + (int)(Math.random() * (right - left + 1));
13+
// Swap the randomly chosen pivot with the rightmost element to
14+
// position the pivot at the rightmost index.
15+
swap(nums, randomIndex, right);
16+
int pivotIndex = partition(nums, left, right);
17+
quicksortOptimized(nums, left, pivotIndex - 1);
18+
quicksortOptimized(nums, pivotIndex + 1, right);
19+
}
20+
21+
private int partition(int[] nums, int left, int right) {
22+
int pivot = nums[right];
23+
int lo = left;
24+
// Move all numbers less than the pivot to the left, which
25+
// consequently positions all numbers greater than or equal to the
26+
// pivot to the right.
27+
for (int i = left; i < right; i++) {
28+
if (nums[i] < pivot) {
29+
swap(nums, lo, i);
30+
lo++;
31+
}
32+
}
33+
// After partitioning, 'lo' will be positioned where the pivot should
34+
// be. So, swap the pivot number with the number at the 'lo' pointer.
35+
swap(nums, lo, right);
36+
return lo;
37+
}
38+
39+
private void swap(int[] nums, int a, int b) {
40+
int tmp = nums[a];
41+
nums[a] = nums[b];
42+
nums[b] = tmp;
43+
}
44+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import DS.ListNode;
2+
3+
/*
4+
// Definition of ListNode:
5+
class ListNode {
6+
public int val;
7+
public ListNode next;
8+
public ListNode(int val) { this.val = val; }
9+
public ListNode(int val, ListNode next) {
10+
this(val);
11+
this.next = next;
12+
}
13+
}
14+
*/
15+
16+
17+
public class SortLinkedList {
18+
public ListNode sortLinkedList(ListNode head) {
19+
// If the linked list is empty or has only one element, it's already
20+
// sorted.
21+
if (head == null || head.next == null) return head;
22+
// Split the linked list into halves using the fast and slow pointer
23+
// technique.
24+
ListNode secondHead = splitList(head);
25+
// Recursively sort both halves.
26+
ListNode firstHalfSorted = sortLinkedList(head);
27+
ListNode secondHalfSorted = sortLinkedList(secondHead);
28+
// Merge the sorted sublists.
29+
return merge(firstHalfSorted, secondHalfSorted);
30+
}
31+
32+
private ListNode splitList(ListNode head) {
33+
ListNode slow;
34+
ListNode fast;
35+
slow = fast = head;
36+
while (fast.next != null && fast.next.next != null) {
37+
slow = slow.next;
38+
fast = fast.next.next;
39+
}
40+
ListNode secondHead = slow.next;
41+
slow.next = null;
42+
return secondHead;
43+
}
44+
45+
private ListNode merge(ListNode l1, ListNode l2) {
46+
ListNode dummy = new ListNode(0);
47+
// This pointer will be used to append nodes to the tail of the
48+
// merged linked list.
49+
ListNode tail = dummy;
50+
// Continually append the node with the smaller value from each
51+
// linked list to the merged linked list until one of the linked
52+
// lists has no more nodes to merge.
53+
while (l1 != null && l2 != null) {
54+
if (l1.val < l2.val) {
55+
tail.next = l1;
56+
l1 = l1.next;
57+
} else {
58+
tail.next = l2;
59+
l2 = l2.next;
60+
}
61+
tail = tail.next;
62+
}
63+
// One of the two linked lists could still have nodes remaining.
64+
// Attach those nodes to the end of the merged linked list.
65+
tail.next = l1 == null ? l2 : l1;
66+
return dummy.next;
67+
}
68+
}

0 commit comments

Comments
 (0)