// O(n^2)
class Solution {
fun twoSum(nums: IntArray, target: Int): IntArray {
for (i in 0 until nums.size - 1) {
for (j in i + 1 until nums.size) {
if (nums[i] + nums[j] == target) {
return intArrayOf(i, j)
}
}
}
return intArrayOf()
}
}
// O(n)
class Solution {
fun twoSum(nums: IntArray, target: Int): IntArray {
val map = HashMap<Int, Int>()
for ((i, v) in nums.withIndex()) {
map[v] = i
}
for ((i, v) in nums.withIndex()) {
val anotherValue = target - v
if (map.containsKey(anotherValue) && map[anotherValue] != i) {
return intArrayOf(i, map[anotherValue]!!)
}
}
return intArrayOf()
}
}
// From left to right, get the min number of the start of nums1 or nums2.
// Step by step, we can get the nTh big number of the two array.
// var totalSize = nums1.size + nums2.size
// var ave = totalSize / 2
// if totalSize is odd, the result is (ave+1)th number;
// else ,there result is ((ave)th number+ (ave+1)th number) / 2
//
// Time Complexity O((m+n)/2)
// Space complexity O(1)
//
// Runtime: 300 ms, faster than 100.00% of Kotlin online submissions for Median of Two Sorted Arrays.
class Solution {
var p1 = -1
var p2 = -1
fun findMedianSortedArrays(nums1: IntArray, nums2: IntArray): Double {
var result = .0
val totalSize = nums1.size + nums2.size
var n = 0
repeat(totalSize / 2) {
n = getNextNumber(nums1, nums2)
}
result = if (totalSize % 2 == 0) {
(n + getNextNumber(nums1, nums2)) / 2.0
} else {
getNextNumber(nums1, nums2).toDouble()
}
return result
}
private fun getNextNumber(nums1: IntArray, nums2: IntArray): Int {
var n = 0
var next1: Int? = null
var next2: Int? = null
if (p1 < nums1.size - 1) {
next1 = nums1[p1 + 1]
}
if (p2 < nums2.size - 1) {
next2 = nums2[p2 + 1]
}
if (next1 == null) {
if (next2 != null) {
p2++
n = next2
}
} else {
n = if (next2 == null) {
p1++
next1
} else {
if (next1 < next2) {
p1++
next1
} else {
p2++
next2
}
}
}
return n
}
}
Stack/Queue
PriorityQueue
LinkedList
/**
* Definition for singly-linked list.
* class ListNode(var `val`: Int = 0) {
* var next: ListNode? = null
* }
*/
class Solution {
fun addTwoNumbers(l1: ListNode?, l2: ListNode?): ListNode? {
var p1 = l1
var p2 = l2
var carry = 0
var sum = 0
val dummyHead: ListNode = ListNode(0)
var curr: ListNode? = dummyHead
while (p1 != null || p2 != null || carry != 0) {
sum = getValueOrZero(p1) + getValueOrZero(p2) + carry
carry = sum / 10
curr?.next = ListNode(sum % 10)
curr = curr?.next
p1 = p1?.next
p2 = p2?.next
}
return dummyHead.next
}
private fun getValueOrZero(l: ListNode?): Int {
return l?.`val` ?: 0
}
}
import java.util.LinkedList
class Solution {
fun lengthOfLongestSubstring(s: String): Int {
var max = 0
val list = LinkedList<Char>()
for (c in s.toCharArray()) {
val indexOfCharInString = list.lastIndexOf(c)
if (indexOfCharInString != -1) {
for (i in 0..indexOfCharInString) {
list.removeFirst()
}
}
list.add(c)
if (list.size > max) {
max = list.size
}
}
return max
}
}
Queue/Priority queue
Stack
Tree/Binary Search Tree
Hash Table
Disjoint Set
Trie
BoolmFilter
LRU Cache
Algorithm
Greedy
Recursion/Backtrace
Traversal
Breadth-First-Search/Depth-First-Search
Divider and Conquer
Dynamic Programming
class Solution {
var start = 0
var end = 0
var max = 0
fun longestPalindrome(s: String): String {
if (s.isEmpty()) {
return s
}
val ca = s.toCharArray()
for (i in 0 until s.length) {
var j = 0
var k = 0
while (i + j + 1 < s.length) {
// handle situations like "aa..."if (ca[i] == ca[i + 1 + j]) {
updateMaxIfNeed(2 + j, i, i + j + 1)
j++
} else {
break
}
}
// expandAroundCenter
while (i - k >= 0 && i + j + k < s.length) {
// dynamic compare start and end char
if (ca[i - k] == ca[i + j + k]) {
updateMaxIfNeed(1 + j + k * 2, i - k, i + k + j)
} else {
break
}
k++
}
}
return s.substring(start, end + 1)
}
private fun updateMaxIfNeed(subLen: Int, s: Int, e: Int) {
if (subLen > max) {
max = subLen
start = s
end = e
}
}
}