第一天 - 数组
1️⃣存在重复元素
题目:给你一个整数数组 nums
。如果任一值在数组中出现 至少两次 ,返回 true
;如果数组中每个元素互不相同,返回 false
。
样例:
思路:本题需要在数组中判断是否存在不同元素,使用Java语言编写时,容易想到使用HashSet来帮助解决
概念:
-
- HashSet类,是存在于java.util包中的类。
- 同时也被称为集合,该容器中只能存储不重复的对象。对于 HashSet 而言,它是基于 HashMap 实现的,底层采用 HashMap 来保存元素。
- 该方法如果添加的是在 HashSet 中不存在的,则返回 true;如果添加的元素已经存在,返回 false。其原因在于我们之前提到的关于 HashMap 的 put 方法
题解:
class Solution {
public boolean containsDuplicate(int[] nums) {
Set<Integer> set = new HashSet<Integer>();//使用HashSet
for(Integer i : nums){
if(!set.add(i)) {//使用集合添加方法
return true;
}
}
return false;
}
}
另解:将数组排序后,逐一比较相邻元素是否相同,但该算法效率低
2️⃣最大子数组和
题目:给你一个整数数组 nums
,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。子数组 是数组中的一个连续部分。
样例:
思路:本题主要需要考虑到如何破解连续最大和,突破点在于一组数之和需要最大,则不应该加入小于零的数,若出现负数,则后一位元素加入后,其自身会受前一位影响而变小,所以使用动态规划思想,把问题分解到每个元素上,在动态遍历的过程中解决。
所以在遍历全组的过程中,先判断当前元素是否为负,若为负,则跳过,不将其加入“最大和子数组”(避免使最大和值减少),遇到不为负的值则将其加入下一元素,修改下一元素值,使其产生累加效果。最终本数组中能够产生的最大和值将在某个元素中保存,只需将其找出即可。
概念:动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。与分治法不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的。
题解:
class Solution {
public int maxSubArray(int[] nums) {
for(int i = 1; i < nums.length; i++) {
if(nums[i-1] > 0) { //前一位元素为正数
nums[i] += nums[i-1]; //当前元素累加前一组数的结果
}
}
Arrays.sort(nums); //将动态规划后的数组排序
return nums[nums.length-1]; //返回最大值即最大和
}
}
第二天 - 数组
3️⃣两数之和
题目:给定一个整数数组 nums
和一个整数目标值 target
,请你在该数组中找出 和为目标值 target
的那 两个 整数,并返回它们的数组下标。你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。你可以按任意顺序返回答案。
样例:
思路:最简单可以想到的就是暴力遍历,这样需要两次循环,时间复杂度来到O(n2)量级
所以本题采用HashMap来解决,map中存储的每个元素都是根据泛型准确定义类型的一对“键-值”对(Key-Value),可以通过键来查值,因为键-值对是唯一匹配的,如果添加进入相同键的值,则后者覆盖前者。
故本题在一次遍历的循环中就能解决问题,原理是:每次循环中判断map中是否存在含有当前元素的键,而当前元素就是所求和减去真实的数组值(我们要匹配的就是是否存在两个元素值之和为所给和),例如有元素[1、2],和为3,则第一次在判断1时,将1存入map,在到2时,判断3-2 = 1,的结果确实存在在map中,所以查找成功。
概念:
-
- HashMap是Java中最常用的集合类框架,也是Java语言中非常典型的数据结构,键值对的集合,源码中每个节点用Node<K,V>表示
- 数组的特点:查询效率高,插入,删除效率低
- 链表的特点:查询效率低,插入删除效率高
- 在HashMap底层使用数组加(链表或红黑树)的结构完美的解决了数组和链表的问题,使得查询和插入,删除的效率都很高
- java1.7 之前HashMap的数据结构为数组+链表 ,之后是 数组+链表+红黑树
题解:
class Solution {
public int[] twoSum(int[] nums, int target) {
int[] getT = new int[2]; //记录结果
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for(int i = 0; i < nums.length; i++) {
if(map.containsKey(target-nums[i])) {//如果map中存在此值的键
return new int[]{i, map.get(target-nums[i])};
}
map.put(nums[i], i); //将遍历过得元素信息加入map中
}
return getT;
}
}