对于算法而言,陌生而神秘,却是成长经历中必经之路。
曾经无数次各种找资料,寻求各种所谓的七天搞定算法秘籍,可结果都是无终而返。
其实换句话来讲,我也是搞 Android 的,有时候看到所谓 7 天让你成为 Android 大牛,也是不屑一顾的。没有长远的积累,哪儿来的大牛?曾经折腾很久的东西,如今 easy 一批,说白了,还是时间久了,写的多了。
一个人,难免会走进各种误区。经历了职场 PUA,顿悟过来,别无他求,自我积累为上。
还是鸡老大的那句话:
- Just do it now.
送给屏幕前的你我,共勉。
针对算法,将采取暴力 Study 法,勤能补拙!多学多练。
个人是个算法白痴,尽量完善每一步,不足之处,欢迎吊打~
欢迎各位大佬吊打~
附上 GitHub 地址:
349. 两个数组的交集
给定两个数组,编写一个函数来计算它们的交集。
示例 1:
输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2]
示例 2:
输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[9,4]
说明:
- 输出结果中的每个元素一定是唯一的。
- 我们可以不考虑输出结果的顺序。
交集概念回顾
以上图为例,A、B 之间重合部分为交集 C。
例如,现有 A、B 如下:
- A:1 3 4 5 6
- B:2 3 3 4
重合部分的内容为:
- 3 4
可得出交集 C 等于 3 4。
交集的概念,用大白话的方式就是,你有我也有,这是交集。此处衍生并集则是,你的加我的,去掉重复的,就是并集。
解题思路 一、Set + contains
大概思路如下:
- 对于输入型数据基本校验,这里不过多解释;
- 通过 Set 唯一特性,过滤第一个数组;
- 将第一个过滤好的数组和第二个数组进行对比,包含,则代表重合,添加 Result 中;
- 遍历 Reslut,赋值 return array
代码如下:
class Solution {
fun intersection(nums1: IntArray, nums2: IntArray): IntArray {
if(nums1.isEmpty() || nums2.isEmpty()){
return IntArray(0)
}
var tempSet = hashSetOf<Int>()
var resultSet = hashSetOf<Int>()
for(num1 in nums1){
tempSet.add(num1)
}
for (num2 in nums2){
if(tempSet.contains(num2)){
resultSet.add(num2)
}
}
var resultIntArray = IntArray(resultSet.size)
var index = 0
for(resultNum in resultSet){
resultIntArray[index++] = resultNum
}
return resultIntArray
}
}
消耗情况:
解题思路 二、Kotlin intersect()
class Solution {
fun intersection(nums1: IntArray, nums2: IntArray): IntArray {
if(nums1.isEmpty() || nums2.isEmpty()){
return IntArray(0)
}
return nums1.intersect(nums2.asList()).toIntArray()
}
}
消耗情况:
相比原始的第一种方案,执行用时以及内存消耗均增加不少,对比代码后,此方式增加了两次转 List 操作。
解题思路 三、继续优化第二条
上面说到,由于多次转 List,造成了一定的消耗,那么接下来,我少创建下,顺便简化下代码呢?
class Solution {
fun intersection(nums1: IntArray, nums2: IntArray): IntArray {
if(nums1.isEmpty() || nums2.isEmpty()){
return IntArray(0)
}
return nums1.intersect(nums2.asList()).toIntArray()
}
}
消耗情况:
有点尴尬咯。
解题思路 四、学习下排序 + 双指针
参考题解:
- [多解法解两个数组的交集[Persian Leopard]](https://leetcode-cn.com/probl...
先附上代码部分:
class Solution {
fun intersection(nums1: IntArray, nums2: IntArray): IntArray {
if(nums1.isEmpty() || nums2.isEmpty()){
return IntArray(0)
}
var i = 0
var j = 0
var index = 0
var resultSet = hashSetOf<Int>()
// 排序的目的是为了下面双指针移动时数据有迹可循,有规律可循
nums1.sort()
nums2.sort()
// 双指针范围不得超出输入数组长度
while (i < nums1.size && j < nums2.size){
// 关键是这块逻辑判断,各位认真画图,很容易理解了
if(nums1[i] == nums2[j]){
resultSet.add(nums1[i])
i++
j++
}else if(nums1[i] < nums2[j]){
i++
}else if(nums1[i] > nums2[j]){
j++
}
}
var resultArray = IntArray(resultSet.size)
for (resultNum in resultSet){
resultArray[index++] = resultNum
}
return resultArray
}
}
消耗程度:
End
单纯的从上图结果来看,还是第一次通过 Set + contains 效率最高。关于双指针这块,虽然是画了很长时间图,赶紧还是理解差点意思。
似乎隐隐约约感受到了算法的重要性,换句话而言的话,也就是算法的思想吧。
不过整体蛮开心的,好歹也算是人生意义上首次搞定啦~
欢迎大佬吊打~
路漫漫其修远兮,吾将上下而求索。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。