LeetCode-Kotlin-Array-EASY-21至30题

关键字

  • PriorityQueue
  • Pair
  • HashMap和HashSet的区别
1.HashMap实现了Map接口,而HashSet实现了Set接口。

2.HashMap用于存储键值对,而HashSet用于存储对象。

3.HashMap不允许有重复的键,可以允许有重复的值。HashSet不允许有重复元素。

4.HashMap允许有一个键为空,多个值为空,HashSet允许有一个空值。

5.HashMap中使用put()将元素加入map中,而HashSet使用add()将元素放入set中。

6.HashMap比较快,因为其使用唯一的键来获取对象。

21.Teemo Attacking

题目大意

在《英雄联盟》的世界中,有一个叫 “提莫” 的英雄。他的攻击可以让敌方英雄艾希(编者注:寒冰射手)进入中毒状态。

当提莫攻击艾希,艾希的中毒状态正好持续duration 秒。

正式地讲,提莫在t发起发起攻击意味着艾希在时间区间 [t, t + duration - 1](含 t 和 t + duration - 1)处于中毒状态。

如果提莫在中毒影响结束前再次攻击,中毒状态计时器将会重置,在新的攻击之后,中毒影响将会在duration秒后结束。

给你一个非递减的整数数组timeSeries,其中timeSeries[i]表示提莫在timeSeries[i]秒时对艾希发起攻击,以及一个表示中毒持续时间的整数duration 。

返回艾希处于中毒状态的总秒数。

解题思路

i 从 1 开始计数,令 t 等于 timeSeries[i - 1]
比较 end(t + duration - 1) 和 timeSeries[i] 的大小,
如果 end 小于 timeSeries[i],ans+=duration
否则 ans += timeSeries[i] - t
ans += duration 并返回 ans

代码

 var timeSeries = intArrayOf(1, 4)
 var duration = 2
 println(findPoisonedDuration(timeSeries, duration))
fun findPoisonedDuration(timeSeries: IntArray, duration: Int): Int {
    
    
    if (timeSeries.isEmpty() || duration == 0) return 0
    var result = 0
    var start = timeSeries[0]
    var end = timeSeries[0] + duration
    for (value in timeSeries) {
    
    
        if (value > end) {
    
    
            result += end - start
            start = value
        }
        end = value + duration
    }
    result += end - start
    return result
}
4

22.Next Greater Element I

题目大意

这道题也是简单题。题目给出 2 个数组 A 和 B,针对 A 中的每个数组中的元素,要求在 B 数组中找出比 A 数组中元素大的数,B 中元素之间的顺序保持不变。如果找到了就输出这个值,如果找不到就输出 -1。

代码

 var nums1 = intArrayOf(4, 1, 2)
    var nums2 = intArrayOf(1, 3, 4, 2)
    println(nextGreaterElement(nums1, nums2).mapIndexed {
    
     index, i -> i })
fun nextGreaterElement(findNums: IntArray, nums: IntArray): IntArray {
    
    
    var map = HashMap<Int, Int>()
    var stack = Stack<Int>()
    for (num in nums) {
    
    
        while (!stack.isEmpty() && stack.peek() < num) {
    
    
            map[stack.pop()] = num
        }
        stack.push(num)
    }
    for (i in findNums.indices) {
    
    
        findNums[i] = map.getOrDefault(findNums[i], -1)
    }
    return findNums
}
[-1, 3, -1]

23.Keyboard Row

题目大意

给定一个单词列表,只返回可以使用在键盘同一行的字母打印出来的单词。键盘如上图所示。

解题思路

给出一个字符串数组,要求依次判断数组中的每个字符串是否都位于键盘上的同一个行,如果是就输出

代码

var words = arrayOf("Hello", "Alaska", "Dad", "Peace")
 println(findWords(words).toMutableList())
fun findWords(words: Array<String>): Array<String> {
    
    
    var strs = arrayOf("QWERTYUIOP", "ASDFGHJKL", "ZXCVBNM")
    var map = HashMap<Char, Int>()
    for (i in strs.indices) {
    
    
        for (c in strs[i].toCharArray()) {
    
    
            map[c] = i
        }
    }
    var res = LinkedList<String>()
    for (w in words) {
    
    
        if (w == "") continue
        var index = map[w.toUpperCase()[0]]
        for (c in w.toUpperCase().toCharArray()) {
    
    
            if (map[c] != index) {
    
    
                index = -1
                break
            }
        }
        if (index != -1) res.add(w)
    }
    return res.toTypedArray()
}
[Alaska, Dad]

24.Relative Ranks

题目大意

给你一个长度为 n 的整数数组 score ,其中 score[i] 是第 i 位运动员在比赛中的得分。所有得分都 互不相同 。

运动员将根据得分 决定名次 ,其中名次第 1 的运动员得分最高,名次第 2 的运动员得分第 2 高,依此类推。运动员的名次决定了他们的获奖情况:

名次第 1 的运动员获金牌 “Gold Medal” 。
名次第 2 的运动员获银牌 “Silver Medal” 。
名次第 3 的运动员获铜牌 “Bronze Medal” 。
从名次第 4 到第 n 的运动员,只能获得他们的名次编号(即,名次第 x 的运动员获得编号 “x”)。

使用长度为 n 的数组 answer 返回获奖,其中 answer[i] 是第 i 位运动员的获奖情况。

解题思路

用 map 记录原来 score 中元素对应的坐标,然后对 score 进行排序,对排序后的元素我们通过 map 就可以知道它排的名次了

代码

 var score = intArrayOf(10, 2, 8, 9, 4)
    println(priorityQueueSol(score))
fun priorityQueueSol(score: IntArray): Array<String> {
    
    
    val queue = PriorityQueue<Pair<Int, Int>>(score.size, Comparator<Pair<Int, Int>> {
    
     o1, o2 ->
        o2.first.compareTo(o1.first)
    })

    score.forEachIndexed {
    
     i, sc ->
        queue.add(Pair(sc, i))
    }
    //queue:[(10, 0), (9, 3), (8, 2), (2, 1), (4, 4)]
  
    val result = Array<String>(score.size) {
    
     "" }
    var i = 0
    while(!queue.isEmpty()) {
    
    
        val pair = queue.poll()
        result[pair.second] = when(i+1) {
    
    
            1 -> "Gold Medal"
            2 -> "Silver Medal"
            3 -> "Bronze Medal"
            else -> (i+1).toString()
        }

        i++
    }

    return result
}
[Gold Medal, 5, Bronze Medal, Silver Medal, 4]

25. Array Partition

题目大意

给定长度为 2n 的数组, 你的任务是将这些数分成 n 对, 例如 (a1, b1), (a2, b2), …, (an, bn) ,使得从1 到 n 的 min(ai, bi) 总和最大。

解题思路

给定一个 2n 个数组,要求把它们分为 n 组一行,求出各组最小值的总和的最大值。
在这里插入图片描述

代码

  var nums = intArrayOf(1, 4, 3, 2)
    println(arrayPairSum(nums))
fun arrayPairSum(nums: IntArray): Int {
    
    
    nums.sort()
    var result = 0
    for (i in nums.indices.step(2)){
    
    
        result+=nums[i]
    }
    return result
}
4

26.Reshape the Matrix

题目大意

在 MATLAB 中,有一个非常有用的函数 reshape,它可以将一个矩阵重塑为另一个大小不同的新矩阵,但保留其原始数据。

给出一个由二维数组表示的矩阵,以及两个正整数r和c,分别表示想要的重构的矩阵的行数和列数。重构后的矩阵需要将原始矩阵的所有元素以相同的行遍历顺序填充。如果具有给定参数的reshape操作是可行且合理的,则输出新的重塑矩阵;否则,输出原始矩阵。
在这里插入图片描述

解题思路

给一个二维数组和 r,c,将这个二维数组“重塑”成行为 r,列为 c。如果可以“重塑”,输出“重塑”以后的数组,如果不能“重塑”,输出原有数组。

代码

 var nums = arrayOf(intArrayOf(1, 2), intArrayOf(3, 4))
    println(matrixReshape(nums, 1, 4).mapIndexed {
    
     index, ints -> ints.toMutableList() })
fun matrixReshape(mat: Array<IntArray>, r: Int, c: Int): Array<IntArray> {
    
    
    if (r * c != mat.size * mat[0].size) {
    
    
        return mat
    }
    var list = mutableListOf<Int>()
    for (i in mat) {
    
    
        for (j in i) list.add(j)
    }
    //list:[1, 2, 3, 4]
    var currentIndex = 0
    val new = Array(r) {
    
     IntArray(c) }
    for (i in new.indices) {
    
    
        val row = new[i]
        for (j in row.indices) {
    
    
            new[i][j] = list[currentIndex]
            currentIndex++
        }
    }
    return new
}
[[1, 2, 3, 4]]

27.Distribute Candies

题目大意

WeChat Official Accounts
Twitter
Weibo

第一章 序章
    1.1 数据结构知识
    1.2 算法知识
    1.3 时间复杂度
第二章 算法专题
    2.01 Array
    2.02 String
    2.03 ✅ Two Pointers
    2.04 ✅ Linked List
    2.05 ✅ Stack
    2.06 Tree
    2.07 Dynamic Programming
    2.08 ✅ Backtracking
    2.09 Depth First Search
    2.10 Breadth First Search
    2.11 Binary Search
    2.12 Math
    2.13 Hash Table
    2.14 ✅ Sorting
    2.15 ✅ Bit Manipulation
    2.16 ✅ Union Find
    2.17 ✅ Sliding Window
    2.18 ✅ Segment Tree
    2.19 ✅ Binary Indexed Tree
第三章 一些模板
    3.1 Segment Tree
    3.2 UnionFind
    3.3 LRUCache
    3.4 LFUCache
    3.5 Binary Indexed Tree
第四章 LeetCode 题解
    0001~0099
    0100~0199
    0200~0299
    0300~0399
    0400~0499
    0500~0599
        0500. Keyboard Row
        0503. Next Greater Element I I
        0504. Base 7
        0506. Relative Ranks
        0507. Perfect Number
        0508. Most Frequent Subtree Sum
        0509. Fibonacci Number
        0513. Find Bottom Left Tree Value
        0515. Find Largest Value in Each Tree Row
        0518. Coin Change I I
        0519. Random Flip Matrix
        0520. Detect Capital
        0523. Continuous Subarray Sum
        0524. Longest Word in Dictionary Through Deleting
        0525. Contiguous Array
        0526. Beautiful Arrangement
        0528. Random Pick With Weight
        0529. Minesweeper
        0530. Minimum Absolute Difference in B S T
        0532. K Diff Pairs in an Array
        0535. Encode and Decode Tiny U R L
        0537. Complex Number Multiplication
        0538. Convert B S T to Greater Tree
        0540. Single Element in a Sorted Array
        0541. Reverse String I I
        0542.01 Matrix
        0543. Diameter of Binary Tree
        0547. Number of Provinces
        0551. Student Attendance Record I
        0554. Brick Wall
        0557. Reverse Words in a String I I I
        0559. Maximum Depth of N Ary Tree
        0560. Subarray Sum Equals K
        0561. Array Partition
        0563. Binary Tree Tilt
        0566. Reshape the Matrix
        0567. Permutation in String
        0572. Subtree of Another Tree
        0575. Distribute Candies
        0576. Out of Boundary Paths
        0581. Shortest Unsorted Continuous Subarray
        0583. Delete Operation for Two Strings
        0589. N Ary Tree Preorder Traversal
        0594. Longest Harmonious Subsequence
        0598. Range Addition I I
        0599. Minimum Index Sum of Two Lists
    0600~0699
    0700~0799
    0800~0899
    0900~0999
    1000~1099
    1100~1199
    1200~1299
    1300~1399
    1400~1499
    1500~1599
    1600~1699
    1700~1799
    1800~1899
    1900~1999
    2000~2099
    2100~2199
    2200~2299
  1. Distribute Candies #
    题目 #

Given an integer array with even length, where different numbers in this array represent different kinds of candies. Each number means one candy of the corresponding kind. You need to distribute these candies equally in number to brother and sister. Return the maximum number of kinds of candies the sister could gain.

Example 1:

Input: candies = [1,1,2,2,3,3]
Output: 3
Explanation:
There are three different kinds of candies (1, 2 and 3), and two candies for each kind.
Optimal distribution: The sister has candies [1,2,3] and the brother has candies [1,2,3], too.
The sister has three different kinds of candies.

Example 2:

Input: candies = [1,1,2,3]
Output: 2
Explanation: For example, the sister has candies [2,3] and the brother has candies [1,1].
The sister has two different kinds of candies, the brother has only one kind of candies.

Note:

The length of the given array is in range [2, 10,000], and will be even.
The number in given array is in range [-100,000, 100,000].

题目大意 #

给定一个偶数长度的数组,其中不同的数字代表着不同种类的糖果,每一个数字代表一个糖果。你需要把这些糖果平均分给一个弟弟和一个妹妹。返回妹妹可以获得的最大糖果的种类数。

解题思路

给出一个糖果数组,里面每个元素代表糖果的种类,相同数字代表相同种类。把这些糖果分给兄弟姐妹,问姐妹最多可以分到多少种糖果。这一题比较简单,用 map 统计每个糖果的出现频次,如果总数比 n/2 小,那么就返回 len(map),否则返回 n/2 (即一半都分给姐妹)。

代码

var nums = intArrayOf(1, 1, 2, 3)
println(distributeCandies(nums))
fun distributeCandies(candies: IntArray): Int {
    
    
    var kinds = HashSet<Int>()
    for (candy in candies) {
    
    
        kinds.add(candy)
    }
    return if (kinds.size >= candies.size / 2) candies.size / 2 else kinds.size
}
2

28.Longest Harmonious Subsequence

题目大意

和谐数组是指一个数组里元素的最大值和最小值之间的差别正好是1。现在,给定一个整数数组,你需要在所有可能的子序列中找到最长的和谐子序列的长度。说明: 输入的数组长度最大不超过20,000.

解题思路

在给出的数组里面找到这样一个子数组:要求子数组中的最大值和最小值相差 1 。这一题是简单题。先统计每个数字出现的频次,然后在 map 找相差 1 的 2 个数组的频次和,动态的维护两个数的频次和就是最后要求的子数组的最大长度。

代码

 var nums = intArrayOf(1, 3, 2, 2, 5, 2, 3, 7)
 println(findLHS(nums))

fun findLHS(nums: IntArray): Int {
    
    
    var m = HashMap<Int, Int>()
    for (num in nums){
    
    
        m.put(num,m.getOrDefault(num,0)+1)
    }
    var max=0
    for ( i in m.keys){
    
    
        if (m.containsKey(i+1)) max=Math.max(max,m.get(i)!!+ m.get(i+1)!!)
    }
    return max
}
5 [3,2,2,2,3]

29.Range Addition II

题目大意

给定一个初始元素全部为 0,大小为 m*n 的矩阵 M 以及在 M 上的一系列更新操作。操作用二维数组表示,其中的每个操作用一个含有两个正整数 a 和 b 的数组表示,含义是将所有符合 0 <= i < a 以及 0 <= j < b 的元素 M[i][j] 的值都增加 1。在执行给定的一系列操作后,你需要返回矩阵中含有最大整数的元素个数。

注意:

m 和 n 的范围是 [1,40000]。
a 的范围是 [1,m],b 的范围是 [1,n]。
操作数目不超过 10000。

在这里插入图片描述
在这里插入图片描述

解题思路

给定一个初始都为 0 的 m * n 的矩阵,和一个操作数组。经过一系列的操作以后,最终输出矩阵中最大整数的元素个数。每次操作都使得一个矩形内的元素都 + 1 。
这一题乍一看像线段树的区间覆盖问题,但是实际上很简单。如果此题是任意的矩阵,那就可能用到线段树了。这一题每个矩阵的起点都包含 [0 , 0] 这个元素,也就是说每次操作都会影响第一个元素。那么这道题就很简单了。经过 n 次操作以后,被覆盖次数最多的矩形区间,一定就是最大整数所在的区间。由于起点都是第一个元素,所以我们只用关心矩形的右下角那个坐标。右下角怎么计算呢?只用每次动态的维护一下矩阵长和宽的最小值即可。

代码

    var m = 3
    var n = 3
    var ops = arrayOf(intArrayOf(2, 2), intArrayOf(3, 3))
    println(maxCount(m, n, ops))
fun maxCount(m: Int, n: Int, ops: Array<IntArray>): Int {
    
    
    if (ops.isEmpty()) return m * n
    var row=Int.MAX_VALUE
    var col=Int.MAX_VALUE
    for (item in ops){
    
    
        row= min(row,item[0])
        col = min(col,item[1])
    }
    return  row * col
}
4

30.Minimum Index Sum of Two Lists

题目大意

假设 Andy 和 Doris 想在晚餐时选择一家餐厅,并且他们都有一个表示最喜爱餐厅的列表,每个餐厅的名字用字符串表示。你需要帮助他们用最少的索引和找出他们共同喜爱的餐厅。 如果答案不止一个,则输出所有答案并且不考虑顺序。 你可以假设总是存在一个答案。

提示:

两个列表的长度范围都在 [1, 1000] 内。
两个列表中的字符串的长度将在 [1,30] 的范围内。
下标从 0 开始,到列表的长度减 1。
两个列表都没有重复的元素。

解题思路

在 Andy 和 Doris 两人分别有各自的餐厅喜欢列表,要求找出两人公共喜欢的一家餐厅,如果共同喜欢的次数相同,都输出。这一题是简单题,用 map 统计频次,输出频次最多的餐厅。

代码

    var list1 = arrayOf("Shogun", "Tapioca Express", "Burger King", "KFC")
    var list2 = arrayOf("KFC", "Shogun", "Burger King")
    println(findRestaurant(list1, list2).toMutableList())
fun findRestaurant(list1: Array<String>, list2: Array<String>): Array<String?> {
    
    
    if (list1.size > list2.size) {
    
    
        return findRestaurant(list2, list1)
    }

    val map1: MutableMap<String, Int> = HashMap()
    for (i in list1.indices) {
    
    
        map1[list1[i]] = i
    }

    var mins: MutableList<String?> = ArrayList()
    var minSum = Int.MAX_VALUE
    for (i in list2.indices) {
    
    
        val rest2 = list2[i]
        if (map1.containsKey(rest2)) {
    
    
            val sum = map1[rest2]!! + i
            if (sum < minSum) {
    
    
                mins = ArrayList()
                minSum = sum
            }
            if (sum == minSum) {
    
    
                mins.add(rest2)
            }
        }
    }

    return mins.toTypedArray()
}
[Shogun]

猜你喜欢

转载自blog.csdn.net/u010194271/article/details/128922680