要快速判断一个元素是否出现集合里的时候,就要考虑哈希法。
题目1:242.有效的字母异位词
思路:将字符串存到哈希表中并计数,遍历另一个字符串做减减操作,如果哈希表里的字符的值都是0才有异位词。
class Solution {
public boolean isAnagram(String s, String t) {
HashMap<Character,Integer> map=new HashMap<Character,Integer>();
for (char c : s.toCharArray()) {
Integer value=map.get(c);
if(value==null){
map.put(c,1);
}else{
value++;
map.put(c,value);
}
}
for (char c : t.toCharArray()) {
Integer value=map.get(c);
if(value==null){
return false;
}else{
value--;
map.put(c,value);
}
}
for (Integer value : map.values()) {
if(value!=0){
return false;
}
}
return true;
}
}
题目2:349. 两个数组的交集
思路:放set集合里,和上道题差不多
class Solution {
public int[] intersection(int[] nums1, int[] nums2) {
HashSet<Integer> map=new HashSet<>();
HashSet<Integer> result=new HashSet<>();
for(int i=0;i<nums1.length;i++){
map.add(nums1[i]);
}
for(int i=0;i<nums2.length;i++){
if(map.contains(nums2[i])){
result.add(nums2[i]);
}
}
return result.stream().mapToInt(x -> x).toArray();
}
}
题目3:第202题. 快乐数
思路:
题目4:1. 两数之和
思路:暴力解法
class Solution {
public int[] twoSum(int[] nums, int target) {
int[] result = new int[2];
for (int i = 0; i < nums.length; i++) {
for (int j = i + 1; j < nums.length; j++) { // 从 i+1 开始查找
if (nums[i] + nums[j] == target) {
result[0] = i;
result[1] = j;
return result; // 找到结果后立即返回
}
}
}
return result;
}
}
题目5:454. 四数相加 II
思路:两个两个数组求和,时间复杂度为n方
class Solution {
public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
int res = 0;
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
//统计两个数组中的元素之和,同时统计出现的次数,放入map
for (int a : nums1) {
for (int b : nums2) {
int sum = a + b;
Integer value=map.get(sum);
if(value==null){
map.put(sum, 1);
}else{
value++;
map.put(sum,value);
}
}
}
for (int c : nums3) {
for (int d : nums4) {
int sum = c + d;
int ab=0-sum;
Integer value=map.get(ab);
if(value!=null){
res+=value;
}
}
}
return res;
}
}
题目6:383. 赎金信
思路:与题目1思路一样
class Solution {
public boolean canConstruct(String ransomNote, String magazine) {
HashMap<Character,Integer> map=new HashMap<Character,Integer>();
for (char c : magazine.toCharArray()) {
Integer value=map.get(c);
if(value==null){
map.put(c,1);
}else{
value++;
map.put(c,value);
}
}
for (char c : ransomNote.toCharArray()) {
Integer value=map.get(c);
if(value==null){
return false;
}else{
value--;
map.put(c,value);
}
}
for (Integer value : map.values()) {
if(value<0){
return false;
}
}
return true;
}
}
题目7:15. 三数之和
思路:双指针法 先固定一个数 剩下用双指针遍历 注意去重
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
//排序
Arrays.sort(nums);
//a+b+c=0 对三个数依次去重
List<List<Integer>> result =new ArrayList<>();
for(int a=0;a<nums.length;a++){
//排序之后如果第一个元素已经大于零 那么无论如何组合都不可能凑成三元组 直接返回
if (nums[a] > 0) {
return result;
}
//对a进行去重 说明与前一个数值相等不用继续收集这个数了
if(a>0&&nums[a]==nums[a-1]){
continue;
}
int left=a+1;
int right=nums.length-1;
//取大于的原因是当left=right时,只剩两个数了,不必收集
while(left<right){
int sum=nums[a]+nums[left]+nums[right];
if(sum>0){
right--;
}else if(sum<0){
left++;
}else{
result.add(Arrays.asList(nums[a], nums[left], nums[right]));
// 去重逻辑应该放在找到一个三元组之后,对b 和 c去重
while(right>left&&nums[right] == nums[right-1]){
right--;
}
while(right>left&&nums[left] == nums[left+1]){
left++;
}
right--;
left++;
}
}
}
return result;
}
}
题目8:18. 四数之和
思路:与三数之和思路一样 确定两个数 剩下两个数做左右指针
class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> result = new ArrayList<>();
Arrays.sort(nums);
for (int k = 0; k < nums.length; k++) {
// nums[k] > target 直接返回 存在k小于0的情况
if (nums[k] > 0 && nums[k] > target) {
return result;
}
if (k > 0 && nums[k - 1] == nums[k]) { // 对nums[k]去重
continue;
}
for (int a = k + 1; a < nums.length; a++) {
if (a > k + 1 && nums[a - 1] == nums[a]) { // 对nums[a]去重
continue;
}
int left = a + 1;
int right = nums.length - 1;
while (right > left) {
// nums[k] + nums[a] + nums[left] + nums[right] > target int会溢出
long sum = (long) nums[k] + nums[a] + nums[left] + nums[right];
if (sum > target) {
right--;
} else if (sum < target) {
left++;
} else {
result.add(Arrays.asList(nums[k], nums[a], nums[left], nums[right]));
// 对nums[left]和nums[right]去重
while (right > left && nums[right] == nums[right - 1]) {
right--;
}
while (right > left && nums[left] == nums[left + 1]){
left++;
}
left++;
right--;
}
}
}
}
return result;
}
}