LeetCode-Kotlin-Array-EASY-31至40题

Posted 黄毛火烧雪下

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode-Kotlin-Array-EASY-31至40题相关的知识,希望对你有一定的参考价值。

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

以上是关于LeetCode-Kotlin-Array-EASY-31至40题的主要内容,如果未能解决你的问题,请参考以下文章