背景
经过面试才知道算法的重要性,无论是社招还是校招,所有大厂都很注重对于算法能力的考察,所以算法简直就是居家旅行升职加薪的必备技能。而且抛去这些功利的想法,算法确实可以锻炼我们的逻辑思维和抽象的能力,这也是程序猿的基本素养。所以我也想专门开一个专栏记录自己的刷题之路,尽可能深入的剖析问题,理解不同的解题思路,而且我也一直在追求技术的全面性而不是囿于移动开发一个领域,所以也会尽可能使用不同的语言,在实践中去领悟不同语言的特性。最后还有一点就是希望找一件事情一直坚持下去,经过多年我发现持之以恒才是这个世界上最难能可贵的品质,一个人的时间是有限的,一个好的习惯可以让我们戒掉一个坏的习惯。
这次刷题会对题目进行分类总结,即会根据数据结构数组、链表和树等归类,也会根据算法如分治法和动态规划等进行总结,题目主要来源于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,会不定期发一些文章和学习资源。
推荐阅读
- 算法|有关for(auto x: vector<int>v)的问题
- CCF-CSP|【手把手刷CCF】201809-2-买菜100分(含详细注释)
- OJ|阶乘分解 kkmd66
- 算法|746. 使用最小花费爬楼梯
- PTA|本题要求编写程序,以hh:mm:ss的格式输出某给定时间再过n秒后的时间值(超过23:59:59就从0点开始计时)。
- 链表|链表的OJ题练习
- LeetCode编程题解法汇总|力扣解法汇总2038- 如果相邻两个颜色均相同则删除当前颜色
- 算法|常用的快速排序
- 蓝桥杯|acwing 1113. 红与黑(蓝桥杯)