力扣爆刷第83天之hot100五连刷1-5
一、1. 两数之和
题目链接:https://leetcode.cn/problems/two-sum/description/?envType=study-plan-v2&envId=top-100-liked
思路:利用hashmap的特性寻找两数之中的另一个即可。
class Solution {
public int[] twoSum(int[] nums, int target) {
Map<Integer, Integer> map = new HashMap<>();
for(int i = 0; i < nums.length; i++) {
int t = target - nums[i];
if(map.containsKey(t)) {
return new int[] {i, map.get(t)};
}else {
map.put(nums[i], i);
}
}
return new int[]{};
}
}
二、49. 字母异位词分组
题目链接:https://leetcode.cn/problems/group-anagrams/description/?envType=study-plan-v2&envId=top-100-liked
思路:要求将字母异位词分组,一看就知道需要使用HashMap进行分组收集,但是我们需要给每一个分组提供一个key,使得同一个分组的字符串经过运算后可以得到一样的key,这样就可以基于一样的key,利用HashMap收集分组,而计算key的方法,我选择将每一个字符串排序,得到正序字符串,用其作为key。
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
Map<String, List<String>> map = new HashMap<>();
List<List<String>> arrayList = new ArrayList<>();
for (String str : strs) {
char[] cArray = str.toCharArray();
Arrays.sort(cArray);
String t = new String(cArray);
List<String> value = map.getOrDefault(t, new ArrayList<String>());
value.add(str);
map.put(t, value);
}
Set<String> set = map.keySet();
for(String s : set) {
arrayList.add(map.get(s));
}
return arrayList;
}
}
三、128. 最长连续序列
题目链接:https://leetcode.cn/problems/longest-consecutive-sequence/description/?envType=study-plan-v2&envId=top-100-liked
思路:本题是乱序的数组,求最长的连续序列,如{4, 3, 100, 1, 2}最长连续序列长度是4,即为1,2,3,4,这种和动态规划中求最长递增子序列,最长重复子序列还不同,明显是无需的序列,还需要把无需给理顺了,题目要求O(n),自然不能排序,数值范围10的9次方,自然不能用数组遍历,这种情况下就应该考虑hashset了,把所有元素添加set之后遍历,只有当前元素是序列的起始元素才会向下求长度,只要不是起始元素,就不进入while,正好所有元素只遍历一遍,时间复杂度为O(n)。
class Solution {
public int longestConsecutive(int[] nums) {
Set<Integer> set = new HashSet<>();
for(int i : nums) {
set.add(i);
}
int max = 0;
for(int i : set) {
if(!set.contains(i-1)) {
int cur = 1;
while(set.contains(i+1)) {
cur++;
i++;
}
max = Math.max(max, cur);
}
}
return max;
}
}
四、283. 移动零
题目链接:https://leetcode.cn/problems/move-zeroes/description/?envType=study-plan-v2&envId=top-100-liked
思路:快慢指针,快指针正常遍历,慢指针不动,直到快指针遇到非0元素,然后与慢指针交换元素,然后慢指针前进一步。原理就是没有0快慢指针就一起动了,有0慢指针就被留下了。
class Solution {
public void moveZeroes(int[] nums) {
int slow = 0;
for(int i = 0; i < nums.length; i++) {
if(nums[i] != 0) {
int temp = nums[slow];
nums[slow] = nums[i];
nums[i] = temp;
slow++;
}
}
}
}
五、11. 盛最多水的容器
题目链接:https://leetcode.cn/problems/container-with-most-water/description/?envType=study-plan-v2&envId=top-100-liked
思路:area = Math.min(nums[left], nums[right]) * (right - left);
当nums[right] >= nums[left] 时,left++所能得到的结果是可能大可能下的,但right–是一定变小的,因为nums[left]决定了上限。
当nums[right]<nums[left]时,right–是可大可小的,但left++,一定是变的更小的,因为此时nums[right]决定了上限。
class Solution {
public int maxArea(int[] height) {
int max = 0, l = 0, r = height.length-1;
while(l < r) {
int cur = Math.min(height[l], height[r]) * (r - l);
max = Math.max(max, cur);
if(height[l] <= height[r]) {
l++;
}else {
r--;
}
}
return max;
}
}