leetcode official wp: 1、枚举 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]; } }
2、哈希表 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]; } }
wp: class Solution { public int longestConsecutive(int[] nums) { HashSet<Integer> numset = new HashSet<>(); for (int num : nums) { numset.add(num); }
int longest = 0; for (int num : numset) { if (!numset.contains(num - 1)) { int initial = num; int next = num + 1; int count = 1; while (numset.contains(next)) { next++; count++; } if (count > longest) { longest = count; } } } return longest; } } 将所有的数存入集合中,可以对数据进行去重,还方便对数字进行搜索。 hashset是由java的hashmap类实现的,哈希表由哈希函数生成,基本操作都是O(1)级别。 存入集合后对数据进行查找,判断该数据是否为序列的起始数据,通过集合中是否包含上一个连续数据即可得知,在寻找到起始数据之后,就可以计算出序列的长度,再比较得到最长的长度。
将序列为分两部分,左指针指向非零序列,右指针指向未排序的序列的首个非零项。 official wp: class Solution { public void moveZeroes(int[] nums) { int n = nums.length,left=0,right=0; while(right<n) { if(nums[right]!=0){ swap(nums,left,right); left++; } right++; } }
public void swap(int[] nums,int left,int right){ int temp = nums[left]; nums[left] = nums[right]; nums[right] = temp; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
fastest wp: class Solution { public void moveZeroes(int[] nums) { int i = 0, j = 0; int len = nums.length; while(i < len && j < len) { if(nums[i] != 0) { nums[j++] = nums[i++]; }else { i++; } } for(i = j; i < len; i++) { nums[i] = 0; } } }
2、盛最多水的容器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。
wp class Solution { public int maxArea(int[] height) { int left = 0,right = height.length-1; int max = 0; while(left<right){ int temp = Math.min(height[left],height[right])*(right-left); if(height[left] < height[right]){ left++; } else{ right--; } max = Math.max(max,temp); } return max; } }
class Solution { public int trap(int[] height) { int res = 0; int left = 0,right = height.length-1; int leftMax = height[left]; int rightMax = height[right]; while(left<right){ if(leftMax<rightMax){ left++; leftMax = Math.max(leftMax,height[left]); res += leftMax - height[left]; } else{ right--; rightMax = Math.max(rightMax,height[right]); res += rightMax - height[right]; } } return res; } }
解法很简洁,虽然想不到,正确性需要证明。
3、滑动窗口
1、无重复字符的最长子串
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
class Solution { public int lengthOfLongestSubstring(String s) { HashSet<Character> charset = new HashSet<>(); int res = 0,left = 0,right = 0;Q for(right=0;right<s.length();right++){ while(charset.contains(s.charAt(right))){ charset.remove(s.charAt(left)); left++; } charset.add(s.charAt(right)); res = Math.max(res,charset.size()); } return res; } }
class Solution { public int subarraySum(int[] nums, int k) { int res=0; for(int i=0;i<nums.length;i++){ int left = i; int right=left; int sum = nums[left]; if(sum == k) { res ++; } while(right<nums.length){ right++; if(right>=nums.length){ break; } sum+=nums[right]; if(sum == k) { res ++; } } } return res; } }
也是暴力出来了,虽然很慢。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
public class Solution { public int subarraySum(int[] nums, int k) { int count = 0, pre = 0; HashMap < Integer, Integer > mp = new HashMap < > (); mp.put(0, 1); for (int i = 0; i < nums.length; i++) { pre += nums[i]; if (mp.containsKey(pre - k)) { count += mp.get(pre - k); } mp.put(pre, mp.getOrDefault(pre, 0) + 1); } return count; } }