package jz.top100;
import java.util.*;
public class Top100 {
//1. 两数之和
public int[] twoSum(int[] nums, int target) {
HashMap<Integer, Integer> map = new HashMap<>();
for(int i = 0; i < nums.length; i++) {
if(map.get(target - nums[i]) != null) {
return new int[]{i, map.get(target - nums[i])};
} else {
map.put(nums[i], i);
}
}
return null;
}
//49. 字母异位词分组
public List<List<String>> groupAnagrams(String[] strs) {
HashMap<String, ArrayList<String>> map = new HashMap<>();
for (String s : strs) {
char[] chars = s.toCharArray();
Arrays.sort(chars);
String s0 = Arrays.toString(chars);
if (map.containsKey(s0)) {
map.get(s0).add(s);
} else {
ArrayList<String> list = new ArrayList<>();
list.add(s);
map.put(s0, list);
}
}
return new ArrayList<List<String>>(map.values());
}
//128. 最长连续序列
//方法1:排序
public int longestConsecutive(int[] nums) {
//数字连续,从任意一个数组出发,遍历最长连续数组
if (nums.length == 0) {
return 0;
}
int cur = 1, max = 1;
Arrays.sort(nums);
for (int i = 1; i < nums.length; i++) {
if (nums[i] == nums[i - 1] + 1) { //连续
cur++;
max = Math.max(max, cur);
} else if (nums[i] == nums[i - 1]){ //相等则忽略
continue;
} else { //不连续,重新开始
cur = 1;
}
}
return max;
}
//方法2:hashset
public int longestConsecutive(int[] nums) {
//hashset记忆
HashSet<Integer> set = new HashSet<>();
for (int num : nums) {
set.add(num);
}
int res = 0;
for (int num : set) { //只需遍历去重后的数字
int cur = num;
//判断当前节点是不是连续序列的起点,不连续才是起点
if (!set.contains(cur - 1)) {
while (set.contains(cur + 1)) {
cur++;
}
}
res = Math.max(res, cur - num + 1);
}
return res;
}
//283. 移动零
public void moveZeroes(int[] nums) {
int n = nums.length;
//把不是0的元素放到前面,剩下的元素置0
int index = 0;
for (int i = 0; i < n; i++) {
if (nums[i] != 0) {
nums[index] = nums[i];
index++;
}
}
for (int i = index; i < n; i++) {
nums[i] = 0;
}
}
//11. 盛最多水的容器
public int maxArea(int[] height) {
if (height.length < 2) {
return 0;
}
int max = 0;
int i = 0, j = height.length - 1;
while (i < j) {
max = Math.max(max, (j - i) * Math.min(height[i], height[j]));
if (height[i] < height[j]) { //向内移动短板
i++;
} else {
j--;
}
}
return max;
}
//15. 三数之和
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
if (nums.length < 3) {
return res;
}
Arrays.sort(nums);
HashMap<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
map.put(nums[i], i);
}
int a, b, c;
for (int i = 0; i < nums.length - 2; i = map.get(a) + 1) {
a = nums[i];
for (int j = i + 1; j < nums.length - 1; j = map.get(b) + 1) {
b = nums[j];
c = -a - b;
if (c < b) {
break;
}
if (map.containsKey(c) && map.get(c) > j) {
ArrayList<Integer> list = new ArrayList<>();
list.add(a);
list.add(b);
list.add(c);
res.add(list);
}
}
}
return res;
}
//42. 接雨水
public int trap(int[] height) {
int res = 0;
for (int i = 1; i < height.length - 1; i++) {
//寻找左边最高的墙
int maxLeft = 0;
for (int j = i - 1; j >= 0; j--) {
if (height[j] > maxLeft) maxLeft = height[j];
}
//寻找右边最高的墙
int maxRight = 0;
for (int j = i + 1; j < height.length; j++) {
if (height[j] > maxRight) maxRight = height[j];
}
//可以存储水的高度取决于较矮的抢
int min = Math.min(maxLeft, maxRight);
if (min > height[i]) {
res += min - height[i];
}
}
return res;
}
//3. 无重复字符的最长子串
public int lengthOfLongestSubstring(String s) {
if (s.length() == 0) return 0;
int left = 0, right = 0, res = 0;
HashMap<Character, Integer> map = new HashMap<>();
while (right < s.length()) {
char c = s.charAt(right);
if (map.containsKey(c)) {
left = Math.max(left, map.get(c) + 1); //使得字串无重复
}
map.put(c, right);
res = Math.max(res, right - left + 1);
right++;
}
return res;
}
//438. 找到字符串中所有字母异位词
public List<Integer> findAnagrams(String s, String p) {
List<Integer> res = new ArrayList<>();
if (s.length() < p.length()) {
return res;
}
//统计滑动窗口内各个字符出现的次数,次数相同,则是异位词
int[] scnt = new int[26];
int[] pcnt = new int[26];
//初始窗口
for (int i = 0; i < p.length(); i++) {
scnt[s.charAt(i) - 'a']++;
pcnt[p.charAt(i) - 'a']++;
}
if (Arrays.equals(scnt, pcnt)) { //判断数组是否相同:Arrays.equals
res.add(0);
}
for (int i = p.length(); i < s.length(); i++) {
//移动窗口,先减去左边界,右边界加1
scnt[s.charAt(i - p.length()) - 'a']--;
scnt[s.charAt(i) - 'a']++;
if (Arrays.equals(scnt, pcnt)) {
res.add(i - p.length() + 1);
}
}
return res;
}
}
LeetCode算法练习top100:(1)哈希、双指针、滑动窗口
于 2023-10-31 21:34:54 首次发布