✨哈喽,进来的小伙伴们,你们好耶!✨
🛰️🛰️系列专栏:【LeetCode面试TOP100】
✈️✈️本篇内容:力扣Top100——第1,2题!
🚀🚀代码存放仓库gitee:力扣面试Top100题!
⛵⛵作者简介:一名双非本科大三在读的科班Java编程小白,道阻且长,星夜启程!
注:每道题的题目就是对应原题的链接,大家可以点过链接直接就可以做题啦!
1. 两数之和
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
示例 1:
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
示例 2:
输入:nums = [3,2,4], target = 6
输出:[1,2]
解法一:暴力枚举
我们可以罗列出数组中的每一个数 x,然后遍历数组查找是否存在 target - x。
当我们使用遍历整个数组的方式寻找 target - x 时,需要注意到每一个位于 x 之前的元素都已经和 x 匹配过,因此不需要再进行匹配。而每一个元素不能被使用两次,所以我们只需要在 x 后面的元素中寻找 target - x。
class Solution {public int[] twoSum(int[] nums, int target) {int n = nums.length;for (int i = 0; i < n; ++i) {for (int j = i + 1; j < n; ++j) {if (nums[i] + nums[j] == target) {return new int[]{i, j};}}}return new int[0];}
}
复杂度分析:
时间复杂度:O(N^2),其中 NN 是数组中的元素数量。最坏情况下数组中任意两个数都要被匹配一次。
空间复杂度:O(1)。
刚才这种解法很直观,看起来也通俗易懂,但是作为咋们专业写代码的同志们来说,做算法题肯定是要考虑到时间复杂度和空间复杂度这个问题的,上述代码的时间复杂度是O(n^2),可以看出时间复杂度非常高,那么有没有简单一点的算法呢?
解法二:哈希表
使用哈希表,可以将寻找 target - x 的时间复杂度降低到从 O(N) 降低到 O(1)。
这样我们创建一个哈希表,对于每一个 x,我们首先查询哈希表中是否存在 target - x,然后将 x 插入到哈希表中,即可保证不会让 x 和自己匹配。
class Solution {public int[] twoSum(int[] nums, int target) {Map<Integer, Integer> hashtable = new HashMap<Integer, Integer>();for (int i = 0; i < nums.length; ++i) {if (hashtable.containsKey(target - nums[i])) {return new int[]{hashtable.get(target - nums[i]), i};}hashtable.put(nums[i], i);}return new int[0];}
}
复杂度分析:
时间复杂度:O(N),其中 NN 是数组中的元素数量。对于每一个元素 x,我们可以 O(1) 地寻找 target - x。
空间复杂度:O(N),其中 NN 是数组中的元素数量。主要为哈希表的开销。
2. 两数相加
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例 1:
示例 2:
输入:l1 = [0], l2 = [0] 输出:[0]
思路:
这题的话是链表逆序排列的,并且每个节点都只存储了一位数字,常规思路遍历L1,L2,将对应位置的数加起来,然后判断有无进位,有的话在额外定义一个变量tmp,用来存储进位,L1,L2可能长度不是一样的,那么就需要在while()循环里面再次判断谁先走完,假如L1先遍历完,那么就继续遍历L2,那么我们这里需要额外定义一个虚拟节点,然后定义一个节点cur等于这个虚拟节点,让cur去动起来,最后返回我们的虚拟节点的next节点便是结果的表头节点,注意最后的进位如果 tmp>0,则需要在额外定义一个新的节点cur.next = new ListNode(tmp)即可。
class Solution {public ListNode addTwoNumbers(ListNode L1, ListNode L2) {ListNode visual = new ListNode();ListNode cur = visual;int tmp = 0;while(L1 != null || L2!=null){int s1 = 0,s2 = 0;s1 = L1 == null?0:L1.val;s2 = L2 == null?0:L2.val;int sum = s1+s2+tmp;cur.next = new ListNode(sum%10);cur = cur.next;tmp = sum/10;if(L1 != null){L1 = L1.next;}if(L2 != null){L2 = L2.next;}}if(tmp != 0) cur.next = new ListNode(tmp);return visual.next;}
}
复杂度分析:
时间复杂度:O(max(m,n)),其中 m 和 n 分别为两个链表的长度。我们要遍历两个链表的全部位置,而处理每个位置只需要 O(1)的时间。
空间复杂度:O(1)。
OK,那么今天的LeetCode打卡就结束了,最近准备持续学习数据结构并且刷题的小伙伴们可以一起打卡LeetCodeTop100题丫!!