File tree Expand file tree Collapse file tree 8 files changed +213
-0
lines changed Expand file tree Collapse file tree 8 files changed +213
-0
lines changed Original file line number Diff line number Diff line change
1
+ fun cuttingWood (heights : List <Int >, k : Int ): Int {
2
+ var left = 0
3
+ var right = heights.maxOrNull()!!
4
+ while (left < right) {
5
+ // Bias the midpoint to the right during the upper-bound binary
6
+ // search.
7
+ val mid = (left + (right - left) / 2 ) + 1
8
+ if (cutsEnoughWood(mid, k, heights)) {
9
+ left = mid
10
+ } else {
11
+ right = mid - 1
12
+ }
13
+ }
14
+ return right
15
+ }
16
+
17
+ // Determine if the current value of 'H' cuts at least 'k' meters of
18
+ // wood.
19
+ fun cutsEnoughWood (H : Int , k : Int , heights : List <Int >): Boolean {
20
+ var woodCollected = 0
21
+ for (height in heights) {
22
+ if (height > H ) {
23
+ woodCollected + = height - H
24
+ }
25
+ }
26
+ return woodCollected >= k
27
+ }
Original file line number Diff line number Diff line change
1
+ fun findTheInsertionIndex (nums : List <Int >, target : Int ): Int {
2
+ var left = 0
3
+ var right = nums.size
4
+ while (left < right) {
5
+ val mid = left + (right - left) / 2
6
+ // If the midpoint value is greater than or equal to the target,
7
+ // the lower bound is either at the midpoint, or to its left.
8
+ if (nums[mid] >= target) {
9
+ right = mid
10
+ // The midpoint value is less than the target, indicating the
11
+ // lower bound is somewhere to the right.
12
+ } else {
13
+ left = mid + 1
14
+ }
15
+ }
16
+ return left
17
+ }
Original file line number Diff line number Diff line change
1
+ fun findTheMedianFromTwoSortedArrays (nums1 : List <Int >, nums2 : List <Int >): Double {
2
+ val m = nums1.size
3
+ val n = nums2.size
4
+ // Ensure 'nums1' is the smaller array.
5
+ if (m > n) {
6
+ return findTheMedianFromTwoSortedArrays(nums2, nums1)
7
+ }
8
+ var left = 0
9
+ var right = m - 1
10
+ val halfTotalLen = (m + n) / 2
11
+ // A median always exists in a non-empty array, so continue binary search until
12
+ // it’s found.
13
+ while (true ) {
14
+ val L1Index = (left + right) / 2
15
+ val L2Index = halfTotalLen - (L1Index + 1 ) - 1
16
+ // Set to -infinity or +infinity if out of bounds.
17
+ val L1 = if (L1Index < 0 ) Double .MIN_VALUE else nums1[L1Index ].toDouble()
18
+ val R1 = if (L1Index >= m - 1 ) Double .MAX_VALUE else nums1[L1Index + 1 ].toDouble()
19
+ val L2 = if (L2Index < 0 ) Double .MIN_VALUE else nums2[L2Index ].toDouble()
20
+ val R2 = if (L2Index >= n - 1 ) Double .MAX_VALUE else nums2[L2Index + 1 ].toDouble()
21
+ // If 'L1 > R2', then 'L1' is too far to the right. Narrow the search space
22
+ // toward the left.
23
+ if (L1 > R2 ) {
24
+ right = L1Index - 1
25
+ // If 'L2 > R1', then 'L1' is too far to the left. Narrow the search space
26
+ // toward the right.
27
+ } else if (L2 > R1 ) {
28
+ left = L1Index + 1
29
+ // If both 'L1' and 'L2' are less than or equal to both 'R1' and 'R2', we
30
+ // found the correct slice.
31
+ } else {
32
+ return if ((m + n) % 2 == 0 ) {
33
+ (maxOf(L1 , L2 ) + minOf(R1 , R2 )) / 2.0
34
+ } else {
35
+ minOf(R1 , R2 )
36
+ }
37
+ }
38
+ }
39
+ }
Original file line number Diff line number Diff line change
1
+ fun findTheTargetInARotatedSortedArray (nums : List <Int >, target : Int ): Int {
2
+ var left = 0
3
+ var right = nums.size - 1
4
+ while (left < right) {
5
+ val mid = left + (right - left) / 2
6
+ if (nums[mid] == target) {
7
+ return mid
8
+ }
9
+ // If the left subarray [left : mid] is sorted, check if the
10
+ // target falls in this range. If it does, search the left
11
+ // subarray. Otherwise, search the right.
12
+ if (nums[left] <= nums[mid]) {
13
+ if (nums[left] <= target && target < nums[mid]) {
14
+ right = mid - 1
15
+ } else {
16
+ left = mid + 1
17
+ }
18
+ // If the right subarray [mid : right] is sorted, check if the
19
+ // target falls in this range. If it does, search the right
20
+ // subarray. Otherwise, search the left.
21
+ } else {
22
+ if (nums[mid] < target && target <= nums[right]) {
23
+ left = mid + 1
24
+ } else {
25
+ right = mid - 1
26
+ }
27
+ }
28
+ }
29
+ return if (nums.isNotEmpty() && nums[left] == target) left else - 1
30
+ }
Original file line number Diff line number Diff line change
1
+ fun firstAndLastOccurrencesOfANumber (nums : List <Int >, target : Int ): List <Int > {
2
+ val lowerBound = lowerBoundBinarySearch(nums, target)
3
+ val upperBound = upperBoundBinarySearch(nums, target)
4
+ return listOf (lowerBound, upperBound)
5
+ }
6
+
7
+ fun lowerBoundBinarySearch (nums : List <Int >, target : Int ): Int {
8
+ var left = 0
9
+ var right = nums.size - 1
10
+ while (left < right) {
11
+ val mid = left + (right - left) / 2
12
+ when {
13
+ nums[mid] > target -> right = mid - 1
14
+ nums[mid] < target -> left = mid + 1
15
+ else -> right = mid
16
+ }
17
+ }
18
+ return if (nums.isNotEmpty() && nums[left] == target) left else - 1
19
+ }
20
+
21
+ fun upperBoundBinarySearch (nums : List <Int >, target : Int ): Int {
22
+ var left = 0
23
+ var right = nums.size - 1
24
+ while (left < right) {
25
+ // In upper-bound binary search, bias the midpoint to the right.
26
+ val mid = (left + (right - left) / 2 ) + 1
27
+ when {
28
+ nums[mid] > target -> right = mid - 1
29
+ nums[mid] < target -> left = mid + 1
30
+ else -> left = mid
31
+ }
32
+ }
33
+ // If the target doesn't exist in the array, then it's possible that
34
+ // 'left = mid + 1' places the left pointer outside the array when
35
+ // 'mid == n - 1'. So, we use the right pointer in the return
36
+ // statement instead.
37
+ return if (nums.isNotEmpty() && nums[right] == target) right else - 1
38
+ }
Original file line number Diff line number Diff line change
1
+ fun localMaximaInArray (nums : List <Int >): Int {
2
+ var left = 0
3
+ var right = nums.size - 1
4
+ while (left < right) {
5
+ val mid = left + (right - left) / 2
6
+ if (nums[mid] > nums[mid + 1 ]) {
7
+ right = mid
8
+ } else {
9
+ left = mid + 1
10
+ }
11
+ }
12
+ return left
13
+ }
Original file line number Diff line number Diff line change
1
+ fun matrixSearch (matrix : List <List <Int >>, target : Int ): Boolean {
2
+ val m = matrix.size
3
+ val n = matrix[0 ].size
4
+ var left = 0
5
+ var right = m * n - 1
6
+ // Perform binary search to find the target.
7
+ while (left <= right) {
8
+ val mid = left + (right - left) / 2
9
+ val r = mid / n
10
+ val c = mid % n
11
+ if (matrix[r][c] == target) {
12
+ return true
13
+ } else if (matrix[r][c] > target) {
14
+ right = mid - 1
15
+ } else {
16
+ left = mid + 1
17
+ }
18
+ }
19
+ return false
20
+ }
Original file line number Diff line number Diff line change
1
+ class WeightedRandomSelection (private val weights : IntArray ) {
2
+ private val prefixSums = IntArray (weights.size)
3
+
4
+ init {
5
+ prefixSums[0 ] = weights[0 ]
6
+ for (i in 1 until weights.size) {
7
+ prefixSums[i] = prefixSums[i - 1 ] + weights[i]
8
+ }
9
+ }
10
+
11
+ fun select (): Int {
12
+ // Pick a random target between 1 and the largest endpoint on the number
13
+ // line.
14
+ val target = (1 .. prefixSums.last()).random()
15
+ var left = 0
16
+ var right = prefixSums.size - 1
17
+ // Perform lower-bound binary search to find which endpoint (i.e., prefix
18
+ // sum value) corresponds to the target.
19
+ while (left < right) {
20
+ val mid = left + (right - left) / 2
21
+ if (prefixSums[mid] < target) {
22
+ left = mid + 1
23
+ } else {
24
+ right = mid
25
+ }
26
+ }
27
+ return left
28
+ }
29
+ }
You can’t perform that action at this time.
0 commit comments