41. 缺失的第一个正数
给你一个未排序的整数数组,请你找出其中没有出现的最小的正整数。
示例 1:
输入: [1,2,0]
输出: 3
示例 2:
输入: [3,4,-1,1]
输出: 2
示例 3:
输入: [7,8,9,11,12]
输出: 1
提示:
你的算法的时间复杂度应为O(n),并且只能使用常数级别的额外空间。
fun _0041_firstMissingPositive() {
println("--------_0041_firstMissingPositive-------")
println(firstMissingPositive(intArrayOf(1, 2, 0)))
println(firstMissingPositive(intArrayOf(3, 4, -1, 1)))
println(firstMissingPositive(intArrayOf(7, 8, 9, 11, 12)))
}
fun firstMissingPositive(nums: IntArray): Int {
val n = nums.size
for (i in nums.indices) {
while (nums[i] in 1..n && nums[nums[i] - 1] != nums[i]) {
swap(i, nums[i] - 1, nums)
}
}
for (i in nums.indices) {
if (nums[i] != i + 1)
return i + 1
}
return n + 1
}
42. 接雨水
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
示例 1:
输入:height = [0,1,0,2,1,0,1,3,2,1,2,1]
输出:6
解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。
示例 2:
输入:height = [4,2,0,3,2,5]
输出:9
提示:
n == height.length
0 <= n <= 3 * 104
0 <= height[i] <= 105
fun _0042_trap() {
println("--------_0042_trap-------")
println(trap(intArrayOf(0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1)))
println(trap(intArrayOf(4, 2, 0, 3, 2, 5)))
}
fun trap(height: IntArray): Int {
var left = 0
var right = height.size - 1
var level = 0
var res = 0
while (left < right) {
val lower = height[if (height[left] < height[right]) left++ else right--]
level = Math.max(level, lower)
res += level - lower
}
return res
}
43. 字符串相乘
给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。
示例 1:
输入: num1 = "2", num2 = "3"
输出: "6"
示例 2:
输入: num1 = "123", num2 = "456"
输出: "56088"
说明:
num1 和 num2 的长度小于110。
num1 和 num2 只包含数字 0-9。
num1 和 num2 均不以零开头,除非是数字 0 本身。
不能使用任何标准库的大数类型(比如 BigInteger)或直接将输入转换为整数来处理。
fun _0043_multiply() {
println("--------_0043_multiply-------")
println(multiply("2", "3"))
println(multiply("8", "22"))
println(multiply("123", "456"))
}
fun multiply(num1: String, num2: String): String {
var res = StringBuffer()
val m = num1.length
val n = num2.length
val vals = IntArray(m + n)
for (i in m - 1 downTo 0) {
for (j in n - 1 downTo 0) {
val mul = (num1[i] - '0') * (num2[j] - '0')
val p1 = i + j
val p2 = i + j + 1
val sum = mul + vals[p2]
vals[p1] += sum / 10
vals[p2] = sum % 10
}
}
for (v in vals) {
if (res.isNotEmpty() || v != 0)
res.append((v))
}
return if (res.isEmpty()) "0" else res.toString()
}
44. 通配符匹配
给定一个字符串 (s) 和一个字符模式 (p) ,实现一个支持 '?' 和 '*' 的通配符匹配。
'?' 可以匹配任何单个字符。
'*' 可以匹配任意字符串(包括空字符串)。
两个字符串完全匹配才算匹配成功。
说明:
s 可能为空,且只包含从 a-z 的小写字母。
p 可能为空,且只包含从 a-z 的小写字母,以及字符 ? 和 *。
示例 1:
输入:
s = "aa"
p = "a"
输出: false
解释: "a" 无法匹配 "aa" 整个字符串。
示例 2:
输入:
s = "aa"
p = "*"
输出: true
解释: '*' 可以匹配任意字符串。
示例 3:
输入:
s = "cb"
p = "?a"
输出: false
解释: '?' 可以匹配 'c', 但第二个 'a' 无法匹配 'b'。
示例 4:
输入:
s = "adceb"
p = "*a*b"
输出: true
解释: 第一个 '*' 可以匹配空字符串, 第二个 '*' 可以匹配字符串 "dce".
示例 5:
输入:
s = "acdcb"
p = "a*c?b"
输出: false
fun _0044_isMatch() {
println("--------_0044_isMatch-------")
println(isMatch1("aa", "a"))
println(isMatch1("aa", "*"))
println(isMatch1("cb", "?a"))
println(isMatch1("adceb", "*a*b"))
println(isMatch1("acdcb", "a*c?b"))
}
fun isMatch1(s: String, p: String): Boolean {
var i = 0
var j = 0
var iStar = -1
var jStar = -1
val m = s.length
val n = p.length
while (i < m) {
if (j < n && (s[i] == p[j] || p[j] == '?')) {
++i
++j
} else if (j < n && p[j] == '*') {
iStar = i
jStar = j++
} else if (iStar >= 0) {
i = ++iStar
j = jStar + 1
} else return false
}
while (j < n && p[j] == '*')
++j
return j == n
}
45. 跳跃游戏 II
给定一个非负整数数组,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
你的目标是使用最少的跳跃次数到达数组的最后一个位置。
示例:
输入: [2,3,1,1,4]
输出: 2
解释: 跳到最后一个位置的最小跳跃数是 2。
从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。
说明:
假设你总是可以到达数组的最后一个位置。
fun _0045_jump() {
println("--------_0045_jump-------")
println(jump(intArrayOf(2, 3, 1, 1, 4)))
}
fun jump(nums: IntArray): Int {
var res = 0
val n = nums.size
var last = 0
var cur = 0
for (i in nums.indices) {
cur = Math.max(cur, i + nums[i])
if (i == last) {
last = cur
++res
if (cur >= n - 1) break
}
}
return res
}
我是今阳,如果想要进阶和了解更多的干货,欢迎关注公众号”今阳说“接收我的最新文章