每日算法之数组(一)

背景 经过面试才知道算法的重要性,无论是社招还是校招,所有大厂都很注重对于算法能力的考察,所以算法简直就是居家旅行升职加薪的必备技能。而且抛去这些功利的想法,算法确实可以锻炼我们的逻辑思维和抽象的能力,这也是程序猿的基本素养。所以我也想专门开一个专栏记录自己的刷题之路,尽可能深入的剖析问题,理解不同的解题思路,而且我也一直在追求技术的全面性而不是囿于移动开发一个领域,所以也会尽可能使用不同的语言,在实践中去领悟不同语言的特性。最后还有一点就是希望找一件事情一直坚持下去,经过多年我发现持之以恒才是这个世界上最难能可贵的品质,一个人的时间是有限的,一个好的习惯可以让我们戒掉一个坏的习惯。
这次刷题会对题目进行分类总结,即会根据数据结构数组、链表和树等归类,也会根据算法如分治法和动态规划等进行总结,题目主要来源于leetcode。
题目 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target的那 两个 整数,并返回它们的数组下标。你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
示例

输入:nums = [2,7,11,15], target = 9输出:[0,1]解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。

输入: nums = [3,2,4], target = 6 输出: [1,2]

输入: nums = [3,3], target = 6 输出: [0,1]

解题思路
暴力枚举 这是一道数组简单题,没有太多复杂的算法,主要考察对于基本的数组操作,最先想到的可以通过两次枚举来寻找合适的对象,而且第二次枚举可以从第一次枚举开始的下一项开始。
JAVA
class Solution { public int[] twoSum(int[] nums, int target) { for (int i = 0; i < nums.length; i++) { for (int j = i + 1; j < nums.length; j++) { if (nums[i] + nums[j] == target) { return new int[]{i, j}; } } } return new int[0]; } }

Python3
class Solution: def twoSum(self, nums: List[int], target: int) -> List[int]: for i in range(0, len(nums)): for j in range(0, len(nums)): if nums[i] + nums[j] == target: return [i, j] return []

C++
class Solution { public: vector twoSum(vector& nums, int target) { int size = nums.size(); for (int i = 0; i < size; ++i) { for (int j = i + 1; j < size; j++) { if (nums[i] + nums[j] == target) { return {i, j}; } } } return {}; } };

哈希表 上面暴力枚举的方法虽然可以解决问题,但是因为需要两次遍历时间复杂度较高,可以引入哈希表在牺牲一定空间的前提下降低时间复杂度。遍历时先判断哈希表中是否有target - nums[i],如果有就返回结果,如果没有则将数组值作为Key,数组索引作为Value存入哈希表。这里拿数组值作为Key可能会有冲突,但是这不影响最终结果。例如数组[2, 2, 1],目标值为3,最后返回结果为[1, 2],因为相同的数组值只会在遍历时更新哈希表对应的Key的Value,而判断条件是通过Key,所以不会影响。
JAVA
class Solution { public int[] twoSum(int[] nums, int target) { Map hashtable = new HashMap<>(); for (int i = 0; i < nums.length; i++) { if (hashtable.containsKey(target - nums[i])) { return new int[]{hashtable.get(target - nums[i]), i}; } else { hashtable.put(nums[i], i); } } return new int[0]; } }

Pyhton3
class Solution: def twoSum(self, nums: List[int], target: int) -> List[int]: hashtable = {} for i, num in enumerate(nums): if target - num in hashtable: return [hashtable[target - num], i] hashtable[num] = i return []

C++
class Solution { public: vector twoSum(vector& nums, int target) { unordered_map hashtable; for (int i = 0; i < nums.size(); i++) { auto it = hashtable.find(target - nums[i]); if (it != hashtable.end()) { return {it->second, i}; } hashtable[nums[i]] = i; } return {}; } };

最后
【每日算法之数组(一)】有兴趣可以关注公众号QStack,会不定期发一些文章和学习资源。

    推荐阅读