31.Can Place Flowers
题目大意
假设你有一个很长的花坛,一部分地块种植了花,另一部分却没有。可是,花卉不能种植在相邻的地块上,它们会争夺水源,两者都会死去。给定一个花坛(表示为一个数组包含0和1,其中0表示没种植花,1表示种植了花),和一个数 n 。能否在不打破种植规则的情况下种入 n 朵花?能则返回True,不能则返回False。
解题思路
这一题最容易想到的解法是步长为 2 遍历数组,依次计数 0 的个数。有 2 种特殊情况需要单独判断,第一种情况是首尾连续多个 0,例如,00001 和 10000,第二种情况是 2 个 1 中间存在的 0 不足以种花,例如,1001 和 100001,1001 不能种任何花,100001 只能种一种花。单独判断出这 2 种情况,这一题就可以 AC 了。
换个思路,找到可以种花的基本单元是 00,那么上面那 2 种特殊情况都可以统一成一种情况。判断是否当前存在 00 的组合,如果存在 00 的组合,都可以种花。末尾的情况需要单独判断,如果末尾为 0,也可以种花。这个时候不需要再找 00 组合,因为会越界。代码实现如下,思路很简洁明了。
eg
Example 1:
Input: flowerbed = [1,0,0,0,1], n = 1
Output: true
Example 2:
Input: flowerbed = [1,0,0,0,1], n = 2
Output: false
代码
var flowerbed = intArrayOf(1, 0, 0, 0, 1)
var n = 1
println(canPlaceFlowers(flowerbed, n))
fun canPlaceFlowers(flowerbed: IntArray, n: Int): Boolean {
var count = 0
var i = 0
while (i < flowerbed.size && count < n) {
if (flowerbed[i] == 0) {
var next = if (i == flowerbed.size - 1) 0 else flowerbed[i + 1]
var prev = if (i == 0) 0 else flowerbed[i - 1]
if (next ==0 && prev==0){
flowerbed[i]=1
count++
}
}
i++
}
return count ==n
}
true
32.Maximum Product of Three Numbers
题目大意
给定一个整型数组,在数组中找出由三个数组成的最大乘积,并输出这个乘积。
解题思路
给出一个数组,要求求出这个数组中任意挑 3 个数能组成的乘积最大的值。
题目的 test case 数据量比较大,如果用排序的话,时间复杂度高,可以直接考虑模拟,挑出 3 个数组成乘积最大值,必然是一个正数和二个负数,或者三个正数。那么选出最大的三个数和最小的二个数,对比一下就可以求出最大值了。时间复杂度 O(n)
eg
Example 1:
Input: [1,2,3]
Output: 6
Example 2:
Input: [1,2,3,4]
Output: 24
代码
var nums = intArrayOf(1, 2, 3)
println(maximumProduct(nums))
fun maximumProduct(nums: IntArray): Int {
var max1 = Int.MIN_VALUE
var max2 = Int.MIN_VALUE
var max3 = Int.MIN_VALUE
var min1 = Int.MAX_VALUE
var min2 = Int.MAX_VALUE
for (n in nums) {
if (n > max1) {
max3 = max2
max2 = max1
max1 = n
} else if (n > max2) {
max3 = max2
max2 = n
} else if (n < max3) {
max3 = n
}
if (n < min1) {
min2 = min1
min1 = n
} else if (n < min2) {
min2 = n
}
}
return max(max1 * max2 * max3, max1 * min1 * min2)
}
6
33.Maximum Average Subarray I
题目大意
给定 n 个整数,找出平均数最大且长度为 k 的连续子数组,并输出该最大平均数。
解题思路
循环一次,扫描数组过程中累加窗口大小为 k 的元素值。不断更新这个最大值。循环结束求出平均值即可。
eg
Input: nums = [1,12,-5,-6,50,3], k = 4
Output: 12.75000
Explanation: Maximum average is (12 - 5 - 6 + 50) / 4 = 51 / 4 = 12.75
代码
var nums = intArrayOf(1, 12, -5, -6, 50, 3)
var k = 4
println(findMaxAverage(nums, k))
fun findMaxAverage(nums: IntArray, k: Int): Double {
var sum = 0
for (i in 0 until k) sum += nums[i]
var max = sum
for (i in k until nums.size) {
sum += nums[i] - nums[i - k]
max = Math.max(max, sum)
}
return max / 1.0 / k
}
12.75
34.Set Mismatch
题目大意
集合 S 包含从1到 n 的整数。不幸的是,因为数据错误,导致集合里面某一个元素复制了成了集合里面的另外一个元素的值,导致集合丢失了一个整数并且有一个元素重复。给定一个数组 nums 代表了集合 S 发生错误后的结果。你的任务是首先寻找到重复出现的整数,再找到丢失的整数,将它们以数组的形式返回。
注意:
给定数组的长度范围是 [2, 10000]。
给定的数组是无序的。
解题思路
给出一个数组,数组里面装的是 1-n 的数字,由于错误导致有一个数字变成了另外一个数字,要求找出重复的一个数字和正确的数字。这一题是简单题,根据下标比对就可以找到哪个数字重复了,哪个数字缺少了。
eg
Input: nums = [1,2,2,4]
Output: [2,3]
代码
var nums = intArrayOf(1, 2, 2, 4)
println(findErrorNums(nums).toMutableList())
fun findErrorNums(nums: IntArray): IntArray {
var dup = 0
var miss = 0
var set = hashSetOf<Int>()
for (i in nums) {
if (set.contains(i)) dup = i
set.add(i)
}
for (j in 1 ..nums.size) {
if (!set.contains(j)) {
miss = j
break
}
}
return intArrayOf(dup, miss)
}
[2, 4]
35.Image Smoother
题目大意
包含整数的二维矩阵 M 表示一个图片的灰度。你需要设计一个平滑器来让每一个单元的灰度成为平均灰度 (向下舍入) ,平均灰度的计算是周围的8个单元和它本身的值求平均,如果周围的单元格不足八个,则尽可能多的利用它们。
解题思路
将二维数组中的每个元素变为周围 9 个元素的平均值。
简单题,按照题意计算平均值即可。需要注意的是边界问题,四个角和边上的元素,这些点计算平均值的时候,计算平均值都不足 9 个元素。
代码
36.Longest Continuous Increasing Subsequence
题目大意
给定一个未经排序的整数数组,找到最长且 连续递增的子序列,并返回该序列的长度。连续递增的子序列 可以由两个下标 l 和 r(l < r)确定,如果对于每个 l <= i < r,都有 nums[i] < nums[i + 1] ,那么子序列 [nums[l], nums[l + 1], …, nums[r - 1], nums[r]] 就是连续递增子序列。
解题思路
这一题要求子序列必须是连续下标,所以变简单了。扫描一遍数组,记下连续递增序列的长度,动态维护这个最大值,最后输出即可。
eg
Input: nums = [1,3,5,4,7]
Output:
Input: nums = [2,2,2,2,2]
Output: 1
代码
var nums = intArrayOf(1, 3, 5, 4, 7)
println(findLengthOfLCIS(nums))
fun findLengthOfLCIS(nums: IntArray): Int {
var res = 0
var cnt = 0
for (i in nums.indices) {
if (i == 0 || nums[i - 1] < nums[i]) {
res = Math.max(res, ++cnt)
} else {
cnt = 1
}
}
return res
}
3
37.Baseball Game
题目大意
这道题是模拟题,给一串数字和操作符。出现数字就直接累加,出现 “C” 就代表栈推出一个元素,相应的总和要减去栈顶的元素。出现 “D” 就代表把前一个元素乘以 2,就得到当前的元素值。再累加。出现 “+” 就代表把前 2 个值求和,得到当前元素的值,再累积。
解题思路
这道题用栈模拟即可。
代码
var nums = arrayOf("5", "2", "C", "D", "+")
println(calPoints(nums))
fun calPoints(operations: Array<String>): Int {
var list = LinkedList<Int>()
var sum = 0
for (op in operations) {
when (op) {
"C" -> {
sum -= list.removeLast()
}
"D" -> {
var item = list.last
list.addLast(item * 2)
sum += item * 2
}
"+" -> {
var value = list[list.size - 2] + list.last
list.addLast(value)
sum += value
}
else -> {
list.addLast(op.toInt())
sum += op.toInt()
}
}
}
return sum
}
30
38.Binary Search
题目大意
给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
解题思路
给出一个数组,要求在数组中搜索等于 target 的元素的下标。如果找到就输出下标,如果找不到输出 -1 。
简单题,二分搜索的裸题。
代码
var nums = intArrayOf(-1, 0, 3, 5, 9, 12)
println(search(nums, 9))
fun search(nums: IntArray, target: Int): Int {
var low = 0
var high = nums.size - 1
while (low <= high) {
var mid = (low + high) / 2
if (nums[mid] == target) return mid
if (nums[mid] < target) low = mid + 1
else high = mid - 1
}
return -1
}
4
39.Design HashSet
题目大意
不使用任何内建的哈希表库设计一个哈希集合具体地说,你的设计应该包含以下的功能:
add(value):向哈希集合中插入一个值。
contains(value) :返回哈希集合中是否存在这个值。
remove(value):将给定值从哈希集合中删除。如果哈希集合中没有这个值,什么也不做。
解题思路
设计一个 hashset 的数据结构,要求有 add(value),contains(value),remove(value),这 3 个方法。
bitset可以说是一个多位二进制数,每八位占用一个字节,因为支持基本的位运算,所以可用于状态压缩,n位bitset执行一次位运算的时间复杂度可视为n/32.
代码
var obj=MyHashSet()
obj.add(1)
println(obj.contains(1))
val bitset = BitSet(1000001)
fun add(key: Int) {
bitset.set(key)
}
fun remove(key: Int) {
bitset.clear(key)
}
fun contains(key: Int): Boolean {
return bitset[key]
}
true
40.Design HashMap
题目大意
不使用任何内建的哈希表库设计一个哈希映射具体地说,你的设计应该包含以下的功能:
put(key, value):向哈希映射中插入(键,值)的数值对。如果键对应的值已经存在,更新这个值。
get(key):返回给定的键所对应的值,如果映射中不包含这个键,返回 -1。
remove(key):如果映射中存在这个键,删除这个数值对。
解题思路
设计一个 hashmap 的数据结构,要求有 put(key, value),get(key),remove(key),这 3 个方法。设计一个 map 主要需要处理哈希冲突,一般都是链表法解决冲突。
代码
var obj=MyHashMap()
obj.put(1,100)
println(obj.get(1))
private val arr = arrayOfNulls<Int>(1000001)
fun put(key: Int, value: Int) {
arr[key] = value
}
fun get(key: Int) = arr[key] ?: -1
fun remove(key: Int) {
arr[key] = null
}
100