每日算法之数组(一)

背景

经过面试才知道算法的重要性,无论是社招还是校招,所有大厂都很注重对于算法能力的考察,所以算法简直就是居家旅行升职加薪的必备技能。而且抛去这些功利的想法,算法确实可以锻炼我们的逻辑思维和抽象的能力,这也是程序猿的基本素养。所以我也想专门开一个专栏记录自己的刷题之路,尽可能深入的剖析问题,理解不同的解题思路,而且我也一直在追求技术的全面性而不是囿于移动开发一个领域,所以也会尽可能使用不同的语言,在实践中去领悟不同语言的特性。最后还有一点就是希望找一件事情一直坚持下去,经过多年我发现持之以恒才是这个世界上最难能可贵的品质,一个人的时间是有限的,一个好的习惯可以让我们戒掉一个坏的习惯。

这次刷题会对题目进行分类总结,即会根据数据结构数组、链表和树等归类,也会根据算法如分治法和动态规划等进行总结,题目主要来源于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,会不定期发一些文章和学习资源。

你可能感兴趣的:(算法)