你好 Leetcode -217 -26 -35 -242 -169 -121

你好 Leetcode -217 -26 -35 -242 -169 -121

这是一个菜鸟自问自答、自言自语的Leetcode刷题笔记

217. 包含重复

题目

哈希表

先用for…of 做一个hashtable出来,再用for…in 检查里面的值有没有任何大于1的就return true 否则就return false (老样子)

 函数包含重复(arr)  
 哈希={}  
 for(let a of arr) //列举arr所有value  
 if (无哈希[a]) 哈希[a]=0  
 哈希[a]+1 for(让 b 在哈希中)  
 如果(哈希 [b]>=2)返回真  
 返回假

Runtime: 274 ms (超慢)
T: O(n)

看了一下讨论区,有一点 改良的方法
第一个for…of的时候已存在=已创过→ 提早直接return

 函数包含重复(arr)  
 哈希={}  
 for(let a of arr) //列举arr所有value  
 if (hash[a]) 返回真  
 哈希[a]=真  
 返回假

Runtime: 111 ms (少跑一圈加速超多XD)
T: O(n)

种类

讨论区 看到的解法
用array内建函式.sort() 排好,然后扫一圈看相邻数字有没有一样的

 函数包含重复(arr)  
 arr.sort()  
 for(i 从 0 到 arr.length)  
 if(arr[i] = arr[i+1]) 返回真 返回假

运行时间:220 毫秒
没有比较快,不过因为不用再多创一个hashtable(object)比较省记体空间
原本作者有提供T/S 复杂度:
时间复杂度: O(NLog(N)) + O(N) = O(NLog(N))
空间复杂度: O(1)

是说.sort()底层是怎么写的没有研究过之后再来看一下 **// 全部**
看到原作者写O(NLog(N))难道是marge sort? (自己之前 笔记 )

讨论区 看到的解法
我跟Set资料结构不熟,只知道set集合里面只能有一个不能有重复的元素
等念完之后补上data structure 笔记 **// 全部** **
** 不过大概看的懂,原理也是利用不能重复的这点
有两个写法,先写比较长的

原理跟hashtable改良版的概念一样,只是改成new set 而不是object
有加到重覆的时候就代表里面已经有了就turn true

 函数包含重复(arr)  
 设置 = 新设置  
 for (i 从 0 到 arr.length)  
 if (set.has arr[i]) 返回真  
 set.add arr[i] 返回假

Runtime: 101 ms (跟hashtable差不多)
原本作者有提供T/S 复杂度:
时间复杂度: O(N) + O(N) = O(N)
空间复杂度: 上)
因为要多做一个set 所以S花比较多

短的写法
也是利用set里面不会有重复的元素
所以说,如果全部元素都是不重复的
那么在set资料结构或者是原本的array都会是一样的数量
如果有重复的会被set滤掉

 函数包含重复(arr)  
 return new Set(arr).size != arr.length

运行时间:152 毫秒
原本作者有提供T/S 复杂度:
时间复杂度: 上)
空间复杂度: 上)

26.从排序数组中删除重复项

题目
限制不能clone 、S 复杂度要O(1)

两点

可能是上次写过类似的题目(283)所以就直觉想要用two points

 函数 removeDuplicates(arr)  
 k = 0  
 for(i 从 0 到 arr.length)  
 if(arr[i] !== arr[i-1])  
 arr[k] = arr[i]  
 k + 1 返回 K

运行时间:82 毫秒
T: O(n)

本来想说可以用set 写然后return .size 跟k会一样
但是后来才想到…..S complexity: O(1)
所以算了XD

拼接

讨论区 看到的解法

 函数 removeDuplicates(arr)  
 for( i 从 0 到 arr.length)  
 如果(arr[i] === arr[i+1])  
 arr.splice(i+1, 1)  
 我-1 返回 arr.length

运行时间:146 毫秒
完全没有比较快,虽然理论上也是T: O(n) (倒车的部分应该不计吧?)
但是边跑回圈边做splice的时候很容易碰到index改变的问题
所以得加i -1检查,不然重复数奇数个的时候会跳过少减一个
但那个-1看着就不是很喜欢,个人应该不太会想用这招

35. 搜索插入位置

题目
限制T complexity: O(log n)

二进制搜索

 函数搜索插入(数字,目标) 最小值 = 0  
 最大值 = nums.length-1  
 中 = 0 而(最大 >= 最小)  
 中=(混合+分钟)/2  
 而(最大 >= 最小)  
 if(nums[mid] = target) 返回中  
 否则如果(目标>nums [mid])  
 最小 = 中 +1  
 别的  
 最大=中 1 返回分钟

运行时间:59 毫秒

同样解法有 递回的写法 补充在整理的 演算法笔记 那边

另外可能这题因为指定T complexity O(log n)的关系
解法好像目前看起来&逛了一下解答区大都是用binary search
如果不限制T complexity的话我应该会直接用回圈解决:

 函数搜索插入(数字,目标){  
 对于(让我=0;我  
 if(nums[i] === 目标 || nums[i] > 目标) 返回 i  
 }  
 返回 nums.length  
 };

不过TO(n)就是了XD
Runtime: 94 ms 的确也是比较慢一点

242. 有效的字谜

题目

哈希表

第一个直觉反应其实是hashtable
然后想也许可以用set stature 解
但是后来才发现要连同个字母的重复各数都完全相等
所以应该是不行用set(至少我爬了一圈文没看到)

 曾是 **是字谜** = 函数(s, t) if(s.length !== t.length) 返回 false 让哈希={} for(让 i of s)  
 if(!hash[i]) 哈希[i]=0  
 哈希[i] ++ for(let j of t)  
 if(!hash[j]) 返回假  
 哈希[j] — for(让 k 在哈希中)  
 if(hash[k] !== 0) 返回 false 返回真

运行时间:119 毫秒
TO(n) (我推测应该是3n 忽略3)

种类

讨论区 看到的解法
切开排好在组回去
还满直觉得但是应该比较慢毕竟用了sort

 var isAnagram = function(s, t) {  
 return s.split('').sort().join('') === t.split('').sort().join('')  
 };

运行时间:127 毫秒
用了sort应该是T: O(n log n)

169. 多数元素

题目

蛮力

跟99乘法表一样用双层回圈
抓一个去第二层数出现次数
抓到了出现次数过半的时候就直接return

T:O(n²)
S:O(1)

哈希表

我第一个反应还是想到用hashtable
key值纪录数字,value纪录出现次数

 var 多数元素 = 函数(arr)  
 哈希 ={}  
 over = arr.length/2 for(让 a 的 arr){  
 if(!hash[a]) 哈希[a]=0  
 哈希[a] ++  
 } for(让 b 在哈希中)  
 如果(哈希 [b] >= 结束)返回 b

用两个for处里,第一个建立hashtable
第二个判断值,找到majore就return
题目说可以预期一定会有majore所以就没加其他处里

运行时间:104 毫秒
T: O(n)
S: O(n) //用了hashtable就S会比较差

看到其他类似解的变形优化版写法:
不用第二个for ,
if判断式直接放在递一个回圈里,直接一边写入的时候一边判断提早return
理论上会快一点,但是T 还是不会变啦

种类

讨论区 看到的解法

觉得违反直觉,忍不住贴去测试结果真的过了XDD
简单来说就是一句话: [整个array的中间会是majore]
用sort排列好,直接取中间那个便是

 var 多数元素 = 函数(数字){  
 nums.sort((a,b) => a - b);  
 返回 nums[Math.floor(nums.length/2)];  
 };

运行时间:118 毫秒
用了sort应该是T: O(n log n)

优点是S: O(1)
不用在额外增加一个object的记忆空间

Boyer-Moore 投票算法

讨论区 看到的解法, 新学到一个演算法!!赶快笔记一下
网路查到有人写 详细说明
这篇的 解答 也写得满清楚的

 [ **Boyer-Moore 投票算法** ] var 多数元素 = 函数(数字){  
      
 让计数 = 0,候选人 = 0  
      
 for(让 nums 的数量){  
 如果(计数 == 0){  
 候选人 = 人数  
 }  
 计数 += 数量 == 候选人? 1:-1  
 }  
      
 返回候选人  
 };

当确定某数n出现次数"确定过半"的时候,其他数出现的总次数一定比n至少少1次
也是有点违反直觉,但仔细想是可行的
这总题型来说这个解法目前看起来应该是T 跟S complexity同时表现最好的

时间复杂度:O(n)
空间复杂度:O(1)

121. 买卖股票的最佳时机

题目

超眼熟觉得之前有解过? 但忘记了XDD

蛮力

两层for回圈第一层起始值i
第二层起始值i+1
穷举所有可能

运行: 超过时限……XD

两个点(?)

宣告左右两个指标跟获利三个变数
while回圈里再用一个变数temp接即时判断最大获利有无更新

 曾是 maxProfit = 函数(价格)  
 left = 0 //购买  
 right = 0 //卖出  
 利润 = 0 而(对  
 如果(价格[右]>价格[左])  
 temp = 价格[右] - 价格[左]  
 利润=温度>利润?温度:利润  
 别的  
 左=右  
 对 ++ 回报利润

Runtime: 143 ms (很慢)
T 复杂度:O(n)
S 复杂度:O(1)

1个指标

讨论区 看到的,跟上面的其实一样
但就是简化完之后用一个指标纪录min 就可以了
(还要一个变数纪录max销售利润)

 var maxProfit = 函数(价格){  
 var min = Number.MAX_SAFE_INTEGER;  
 变量最大值 = 0;  
 for (var i = 0; i < 价格.长度; i++) {  
 min = Math.min(min, 价格[i]);  
 最大值 = Math.max(最大值,价格 [i] - 最小值);  
 }  
 返回最大值;  
 };

Runtime: 95 ms 变快
但T跟S 理论上应该也是跟上面的一样

Number.MAX_SAFE_INTEGER
比较少用记录一下
之前类似的使用情境有用过Infinity
他也有 Number.MIN_SAFE_INTEGER 可以用

数学.min()
数学.max()

也比较少用,不过我觉得我写三元运算子应该也没差别

参考______

  1. set: 演算法笔记

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明

本文链接:https://www.qanswer.top/3070/18023109

posted @ 2022-08-31 09:19  哈哈哈来了啊啊啊  阅读(22)  评论(0编辑  收藏  举报