LeetCode刷题(五)-----数组-------easy部分(Java、C++)

LeetCode刷题(五)-----数组-------easy部分(Java、C++)

167. 两数之和 II - 输入有序数组

给定一个已按照升序排列的有序数组,找到两个数使得它们相加之和等于目标数。
函数应该返回这两个下标值index1和index2,其中index1必须小于index2。

说明:
• 返回的下标值(index1 和 index2)不是从零开始的。
• 你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。
在这里插入图片描述
我的题解:其中双循环超出了时间限制;
LeetCode刷题(五)-----数组-------easy部分(Java、C++)_第1张图片题解一:
方法 1:双指针
算法
我们可以使用两数之和的解法在 O(n^2)时间O(1)空间暴力解决,也可以用哈希表在O(n)时间和O(n)空间内解决。然而,这两种方法都没有用到输入数组已经排序的性质,我们可以做得更好。

我们使用两个指针,初始分别位于第一个元素和最后一个元素位置,比较这两个元素之和与目标值的大小。如果和等于目标值,我们发现了这个唯一解。如果比目标值小,我们将较小元素指针增加一。如果比目标值大,我们将较大指针减小一。移动指针后重复上述比较知道找到答案。

假设[…,a,b,c,…,d,e,f,…]是已经升序排列的输入数组,并且元素b,e是唯一解。因为我们从左到右移动较小指针,从右到左移动较大指针,总有某个时刻存在一个指针移动到b或e的位置。不妨假设小指针先移动到了元素b,这是两个元素的和一定比目标值大,根据我们的算法,我们会向左移动较大指针直至获得结果。
LeetCode刷题(五)-----数组-------easy部分(Java、C++)_第2张图片
是否需要考虑 numbers[low]+numbers[high]溢出呢?答案是不需要。因为即使两个元素之和溢出了,因为只存在唯一解,所以一定会先访问到答案。
复杂度分析
• 时间复杂度:O(n)。每个元素最多被访问一次,共有n个元素。
• 空间复杂度:O(1)。只是用了两个指针。

链接:https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted/solution/liang-shu-zhi-he-ii-shu-ru-you-xu-shu-zu-by-leetco/

题解二:
解法一:双循环,暴力
时间复杂度:O(n^2)
这个很简单,遍历每个元素x,并查找是否存在一个值与target - x 相等的目标元素。
LeetCode刷题(五)-----数组-------easy部分(Java、C++)_第3张图片
解法二:hash表
时间复杂度:O(n)
在这里插入图片描述
套入题目的例子,遍历数组,数组遍历的当前值为numbers[i],那么 y 应该是 target - numbers[i]。
所以,只要在遍历的时候确定target - numbers[i]在数组里有,返回对应下标。

hash表方法有两次哈希表方法和一次哈希表方法。

两次hash表方法,在第一次迭代中,我们将每个元素的值和它的索引添加到表中。然后,在第二次迭代中,我们将检查每个元素所对应的目标元素(target−numbers[i])是否存在于表中。

一次hash表方法,下面代码所示。
LeetCode刷题(五)-----数组-------easy部分(Java、C++)_第4张图片
解法三:双向指针

由于数组是有序的,只需要双指针即可。一个left指针,一个right指针, 如果 left + right 值大于 target 则 right左移动, 否则 left 右移。

如果数组无序,需要先排序。
LeetCode刷题(五)-----数组-------easy部分(Java、C++)_第5张图片
解法四:二分查找
时间复杂度:O(nlogn)
x + y = target, y = target - x
遍历numbers,利用二分查找target-numbers[i]
注意题目要求,其中 index1 必须小于 index2,而且你不可以重复使用相同的元素。
LeetCode刷题(五)-----数组-------easy部分(Java、C++)_第6张图片
链接:https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted/solution/js-xie-leetcode-by-zhl1232-21/

我的第二次答案:
LeetCode刷题(五)-----数组-------easy部分(Java、C++)_第7张图片

169. 求众数

给定一个大小为n的数组,找到其中的众数。众数是指在数组中出现次数大于⌊ n/2 ⌋的元素。
你可以假设数组是非空的,并且给定的数组总是存在众数。

LeetCode刷题(五)-----数组-------easy部分(Java、C++)_第8张图片

思路一:

题目意思很好理解:给你一个数组,里面有一个数字出现的次数超过了一半,你要找到这个数字并返回。
解法一:暴力解法
遍历整个数组,同时统计每个数字出现的次数。
最后将出现次数大于一半的元素返回即可。
代码实现
LeetCode刷题(五)-----数组-------easy部分(Java、C++)_第9张图片
复杂度分析
时间复杂度:O(n2)
暴力解法包含两重嵌套的 for 循环,每一层 n 次迭代,因此时间复杂度为 O(n2) 。
空间复杂度:O(1)
暴力解法没有分配任何与输入规模成比例的额外的空间,因此空间复杂度为 O(1)。

解法二:哈希表法
这个问题可以视为查找问题,对于查找问题往往可以使用时间复杂度为 O(1) 的 哈希表,通过以空间换时间的方式进行优化。
直接遍历整个 数组 ,将每一个数字(num)与它出现的次数(count)存放在 哈希表 中,同时判断该数字出现次数是否是最大的,动态更新 maxCount,最后输出 maxNum。

代码实现
LeetCode刷题(五)-----数组-------easy部分(Java、C++)_第10张图片
复杂度分析
时间复杂度:O(n)
总共有一个循环,里面哈希表的插入是常数时间的,因此时间复杂度为 O(n)。
空间复杂度:O(n)
哈希表占用了额外的空间 O(n),因此空间复杂度为 O(n)。
解法三:摩尔投票法
再来回顾一下题目:寻找数组中超过一半的数字,这意味着数组中其他数字出现次数的总和都是比不上这个数字出现的次数 。
即如果把 该众数记为 +1 ,把其他数记为 −1 ,将它们全部加起来,和是大于 0 的。
所以可以这样操作:
1.设置两个变量 candidate 和 count,candidate 用来保存数组中遍历到的某个数字,count 表示当前数字的出现次数,一开始 candidate 保存为数组中的第一个数字,count 为 1
2.遍历整个数组
3.如果数字与之前 candidate 保存的数字相同,则 count 加 1
4.如果数字与之前 candidate 保存的数字不同,则 count 减 1
5.如果出现次数 count 变为 0 ,candidate 进行变化,保存为当前遍历的那个数字,并且同时把 count 重置为 1
6.遍历完数组中的所有数字即可得到结果
LeetCode刷题(五)-----数组-------easy部分(Java、C++)_第11张图片
链接:https://leetcode-cn.com/problems/majority-element/solution/du-le-le-bu-ru-zhong-le-le-ru-he-zhuang-bi-de-qiu-/
来源:力扣(LeetCode)
我的:
LeetCode刷题(五)-----数组-------easy部分(Java、C++)_第12张图片

你可能感兴趣的:(leetcode刷题专栏,实习,刷题,leetcode,C++,JAVA)