Skip to content

Commit 45660da

Browse files
committed
Merge commit 'f1705c5d2be4fecbe15f4f0be4a39cb1993b6653' into kotlin-trie
2 parents ac6a567 + f1705c5 commit 45660da

16 files changed

+350
-0
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
fun hammingWeightsOfIntegers(n: Int): List<Int> {
2+
return (1..n).map { countSetBits(it) }
3+
}
4+
5+
fun countSetBits(n: Int): Int {
6+
var x = n
7+
var count = 0
8+
// Count each set bit of 'x' until 'x' equals 0.
9+
while (x > 0) {
10+
// Increment the count if the LSB is 1.
11+
count += x.and(1)
12+
// Right shift 'x' to shift the next bit to the LSB position.
13+
x = x.shr(1)
14+
}
15+
return count
16+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
fun hammingWeightsOfIntegersDp(n: Int): List<Int> {
2+
// Base case: the number of set bits in 0 is just 0. We set dp[0] to
3+
// 0 by initializing the entire DP array to 0.
4+
val dp = IntArray(n + 1)
5+
for (x in 1..n) {
6+
// 'dp[x]' is obtained using the result of 'dp[x >> 1]', plus
7+
// the LSB of 'x'.
8+
dp[x] = dp[x ushr 1] + (x and 1)
9+
}
10+
return dp.toList()
11+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
fun lonelyInteger(nums: List<Int>): Int {
2+
var res = 0
3+
// XOR each element of the array so that duplicate values will
4+
// cancel each other out (x ^ x == 0).
5+
for (n in nums) {
6+
res = res.xor(n)
7+
}
8+
// 'res' will store the lonely integer because it would not have
9+
// been canceled out by any duplicate.
10+
return res
11+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
fun swapOddAndEvenBits(n: Long): Long {
2+
val evenMask: Long = 0x55555555 // 01010101010101010101010101010101
3+
val oddMask: Long = 0xAAAAAAAA // 10101010101010101010101010101010
4+
val evenBits = n.toLong() and evenMask
5+
val oddBits = n.toLong() and oddMask
6+
// Shift the even bits to the left, the odd bits to the right, and
7+
// merge these shifted values together.
8+
// shl - signed shift left
9+
// ushr - unsigned shift right
10+
return (evenBits shl 1) or (oddBits ushr 1)
11+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
fun happyNumber(n: Int): Boolean {
2+
var slow = n
3+
var fast = n
4+
while (true) {
5+
slow = getNextNum(slow)
6+
fast = getNextNum(getNextNum(fast))
7+
if (fast == 1) {
8+
return true
9+
// If the fast and slow pointers meet, a cycle is detected.
10+
// Hence, 'n' is not a happy number.
11+
} else if (fast == slow) {
12+
return false
13+
}
14+
}
15+
}
16+
17+
fun getNextNum(x: Int): Int {
18+
var nextNum = 0
19+
var num = x
20+
while (num > 0) {
21+
// Extract the last digit of 'x'.
22+
val digit = num % 10
23+
// Truncate (remove) the last digit from 'x' using floor
24+
// division.
25+
num /= 10
26+
// Add the square of the extracted digit to the sum.
27+
nextNum += digit * digit
28+
}
29+
return nextNum
30+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/*
2+
Definition of ListNode:
3+
data class ListNode(var value: Int, var next: ListNode? = null)
4+
*/
5+
6+
fun linkedListLoop(head: ListNode?): Boolean {
7+
var slow = head
8+
var fast = head
9+
// Check both 'fast' and 'fast.next' to avoid null pointer
10+
// exceptions when we perform 'fast.next' and 'fast.next.next'.
11+
while (fast != null && fast.next != null) {
12+
slow = slow!!.next
13+
fast = fast.next!!.next
14+
if (fast == slow) {
15+
return true
16+
}
17+
}
18+
return false
19+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/*
2+
Definition of ListNode:
3+
data class ListNode(var value: Int, var next: ListNode? = null)
4+
*/
5+
6+
fun linkedListLoopNaive(head: ListNode?): Boolean {
7+
val visited = mutableSetOf<ListNode>()
8+
var curr = head
9+
while (curr != null) {
10+
// Cycle detected if the current node has already been visited.
11+
if (visited.contains(curr)) {
12+
return true
13+
}
14+
visited.add(curr)
15+
curr = curr.next
16+
}
17+
return false
18+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/*
2+
Definition of ListNode:
3+
data class ListNode(var value: Int, var next: ListNode? = null)
4+
*/
5+
6+
fun linkedListMidpoint(head: ListNode?): ListNode? {
7+
var slow = head
8+
var fast = head
9+
// When the fast pointer reaches the end of the list, the slow
10+
// pointer will be at the midpoint of the linked list.
11+
while (fast != null && fast.next != null) {
12+
slow = slow!!.next
13+
fast = fast.next!!.next
14+
}
15+
return slow
16+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
fun geometricSequenceTriplets(nums: List<Int>, r: Int): Int {
2+
// leftMap and rightMap will use 'getOrDefault' to ensure the default value of 0 is returned when
3+
// accessing a key that doesn’t exist in the hash map. This effectively sets
4+
// the default frequency of all elements to 0.
5+
val leftMap = mutableMapOf<Int, Int>()
6+
val rightMap = mutableMapOf<Int, Int>()
7+
var count = 0
8+
// Populate 'rightMap' with the frequency of each element in the array.
9+
for (x in nums) {
10+
rightMap[x] = rightMap.getOrDefault(x, 0) + 1
11+
}
12+
// Search for geometric triplets that have x as the center.
13+
for (x in nums) {
14+
// Decrement the frequency of x in 'rightMap' since x is now being
15+
// processed and is no longer to the right.
16+
rightMap[x] = rightMap.getOrDefault(x, 0) - 1
17+
if (x % r == 0) {
18+
count += leftMap.getOrDefault(x / r, 0) * rightMap.getOrDefault(x * r, 0)
19+
}
20+
// Increment the frequency of x in 'leftMap' since it'll be a part of the
21+
// left side of the array once we iterate to the next value of x.
22+
leftMap[x] = leftMap.getOrDefault(x, 0) + 1
23+
}
24+
return count
25+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
fun longestChainOfConsecutiveNumbers(nums: List<Int>): Int {
2+
if (nums.isEmpty()) {
3+
return 0
4+
}
5+
val numSet = nums.toSet()
6+
var longestChain = 0
7+
for (num in numSet) {
8+
// If the current number is the smallest number in its chain, search for
9+
// the length of its chain.
10+
if (num - 1 !in numSet) {
11+
var currentNum = num
12+
var currentChain = 1
13+
// Continue to find the next consecutive numbers in the chain.
14+
while (currentNum + 1 in numSet) {
15+
currentNum++
16+
currentChain++
17+
}
18+
longestChain = maxOf(longestChain, currentChain)
19+
}
20+
}
21+
return longestChain
22+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
fun longestChainOfConsecutiveNumbersBruteForce(nums: List<Int>): Int {
2+
if (nums.isEmpty()) {
3+
return 0
4+
}
5+
var longestChain = 0
6+
// Look for chains of consecutive numbers that start from each number.
7+
for (num in nums) {
8+
var currentNum = num
9+
var currentChain = 1
10+
// Continue to find the next consecutive numbers in the chain.
11+
while (currentNum + 1 in nums) {
12+
currentNum++
13+
currentChain++
14+
}
15+
longestChain = maxOf(longestChain, currentChain)
16+
}
17+
return longestChain
18+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
fun pairSumUnsortedTwoPass(nums: List<Int>, target: Int): List<Int> {
2+
val numMap = mutableMapOf<Int, Int>()
3+
// First pass: Populate the hash map with each number and its
4+
// index.
5+
for ((i, num) in nums.withIndex()) {
6+
numMap[num] = i
7+
}
8+
// Second pass: Check for each number's complement in the hash map.
9+
for ((i, num) in nums.withIndex()) {
10+
val complement = target - num
11+
if (complement in numMap && numMap[complement] != i) {
12+
return listOf(i, numMap[complement]!!)
13+
}
14+
}
15+
return emptyList()
16+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
fun pairSumUnsorted(nums: List<Int>, target: Int): List<Int> {
2+
val hashmap = mutableMapOf<Int, Int>()
3+
for ((i, x) in nums.withIndex()) {
4+
if (target - x in hashmap) {
5+
return listOf(hashmap[target - x]!!, i)
6+
}
7+
hashmap[x] = i
8+
}
9+
return emptyList()
10+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
fun verifySudokuBoard(board: List<List<Int>>): Boolean {
2+
// Create hash sets for each row, column, and subgrid to keep
3+
// track of numbers previously seen on any given row, column, or
4+
// subgrid.
5+
val rowSets: List<HashSet<Int>> = List(9) {
6+
hashSetOf()
7+
}
8+
val colSets: List<HashSet<Int>> = List(9) {
9+
hashSetOf()
10+
}
11+
val subgridSets: List<List<HashSet<Int>>> = List(3) {
12+
List(3) {
13+
hashSetOf()
14+
}
15+
}
16+
for (r in 0 until 9) {
17+
for (c in 0 until 9) {
18+
val num = board[r][c]
19+
if (num == 0) {
20+
continue
21+
}
22+
// Check if 'num' has been seen in the current row,
23+
// column, or subgrid.
24+
if (rowSets[r].contains(num)) {
25+
return false
26+
}
27+
if (colSets[c].contains(num)) {
28+
return false
29+
}
30+
if (subgridSets[r / 3][c / 3].contains(num)) {
31+
return false
32+
}
33+
// If we passed the above checks, mark this value as seen
34+
// by adding it to its corresponding hash sets.
35+
rowSets[r].add(num)
36+
colSets[c].add(num)
37+
subgridSets[r / 3][c / 3].add(num)
38+
}
39+
}
40+
return true
41+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
fun zeroStriping(matrix: MutableList<MutableList<Int>>) {
2+
if (matrix.isEmpty() || matrix[0].isEmpty()) {
3+
return
4+
}
5+
val m = matrix.size
6+
val n = matrix[0].size
7+
// Check if the first row initially contains a zero.
8+
var firstRowHasZero = false
9+
for (c in 0 until n) {
10+
if (matrix[0][c] == 0) {
11+
firstRowHasZero = true
12+
break
13+
}
14+
}
15+
// Check if the first column initially contains a zero.
16+
var firstColHasZero = false
17+
for (r in 0 until m) {
18+
if (matrix[r][0] == 0) {
19+
firstColHasZero = true
20+
break
21+
}
22+
}
23+
// Use the first row and column as markers. If an element in the
24+
// submatrix is zero, mark its corresponding row and column in the
25+
// first row and column as 0.
26+
for (r in 1 until m) {
27+
for (c in 1 until n) {
28+
if (matrix[r][c] == 0) {
29+
matrix[0][c] = 0
30+
matrix[r][0] = 0
31+
}
32+
}
33+
}
34+
// Update the submatrix using the markers in the first row and
35+
// column.
36+
for (r in 1 until m) {
37+
for (c in 1 until n) {
38+
if (matrix[0][c] == 0 || matrix[r][0] == 0) {
39+
matrix[r][c] = 0
40+
}
41+
}
42+
}
43+
// If the first row had a zero initially, set all elements in the
44+
// first row to zero.
45+
if (firstRowHasZero) {
46+
for (c in 0 until n) {
47+
matrix[0][c] = 0
48+
}
49+
}
50+
// If the first column had a zero initially, set all elements in
51+
// the first column to zero.
52+
if (firstColHasZero) {
53+
for (r in 0 until m) {
54+
matrix[r][0] = 0
55+
}
56+
}
57+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
fun zeroStripingHashSets(matrix: MutableList<MutableList<Int>>) {
2+
if (matrix.isEmpty() || matrix[0].isEmpty()) {
3+
return
4+
}
5+
val m = matrix.size
6+
val n = matrix[0].size
7+
val zeroRows = hashSetOf<Int>()
8+
val zeroCols = hashSetOf<Int>()
9+
// Pass 1: Traverse through the matrix to identify the rows and
10+
// columns containing zeros and store their indexes in the
11+
// appropriate hash sets.
12+
for (r in 0 until m) {
13+
for (c in 0 until n) {
14+
if (matrix[r][c] == 0) {
15+
zeroRows.add(r)
16+
zeroCols.add(c)
17+
}
18+
}
19+
}
20+
// Pass 2: Set any cell in the matrix to zero if its row index is
21+
// in 'zero_rows' or its column index is in 'zero_cols'.
22+
for (r in 0 until m) {
23+
for (c in 0 until n) {
24+
if (r in zeroRows || c in zeroCols) {
25+
matrix[r][c] = 0
26+
}
27+
}
28+
}
29+
}

0 commit comments

Comments
 (0)