leecode更新

This commit is contained in:
markilue 2022-12-27 12:48:31 +08:00
parent a5fca3e288
commit f3e88db25c
9 changed files with 483 additions and 4 deletions

View File

@ -14,7 +14,7 @@ import java.util.HashMap;
* 注意若s t中每个字符出现的次数都相同则称s t互为字母异位词 * 注意若s t中每个字符出现的次数都相同则称s t互为字母异位词
* @Version: 1.0 * @Version: 1.0
*/ */
public class IsAnagram { public class T01_IsAnagram {
@Test @Test

View File

@ -17,7 +17,7 @@ import java.util.Set;
* 给定两个数组 nums1 nums2 返回 它们的交集 输出结果中的每个元素一定是 唯一 我们可以 不考虑输出结果的顺序 * 给定两个数组 nums1 nums2 返回 它们的交集 输出结果中的每个元素一定是 唯一 我们可以 不考虑输出结果的顺序
* @Version: 1.0 * @Version: 1.0
*/ */
public class Intersection { public class T02_Intersection {
@Test @Test
public void test(){ public void test(){

View File

@ -0,0 +1,113 @@
package com.markilue.leecode.hashtable;
import org.junit.Test;
import java.util.HashSet;
import java.util.Set;
/**
*@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.hashtable
*@Author: dingjiawen
*@CreateTime: 2022-12-27 11:06
*@Description:
* TODO 力扣202题 快乐数:
* 编写一个算法来判断一个数 n 是不是快乐数
* 快乐数 定义为
* 对于一个正整数每一次将该数替换为它每个位置上的数字的平方和
* 然后重复这个过程直到这个数变为 1也可能是 无限循环 但始终变不到 1
* 如果这个过程 结果为 1那么这个数就是快乐数
* 如果 n 快乐数 就返回 true 不是则返回 false
*@Version: 1.0
*/
public class T03_IsHappy {
@Test
public void test(){
int n=19;
System.out.println(isHappy(n));
}
@Test
public void test1(){
int n=2;
System.out.println(isHappy(n));
}
/**
* 思路:利用hashset记录重复的一旦重复了就进入了循环那么直接返回false
* 速度击败81.35%内存击败42.29% 1ms
* @param n
* @return
*/
public boolean isHappy(int n) {
HashSet<Integer> set = new HashSet<>();
set.add(n);
while (n!=1){
int next=0;
//计算各个位置之和
while (n!=0){
int num = n % 10;
next+=num*num;
n/=10;
}
if(set.contains(next)){
//已经开始循环直接开始返回
return false;
}else {
set.add(next);
n=next;
}
}
return true;
}
/**
* 官方hash思路:与本人hash
* 利用hashset记录重复的一旦重复了就进入了循环或者等于1那么就可以返回了
* 速度击败81.35%内存击败67.9% 1ms
* 时间复杂度O(logn)
* @param n
* @return
*/
public boolean isHappy1(int n) {
Set<Integer> seen = new HashSet<>();
while (n != 1 && !seen.contains(n)) {
seen.add(n);
n = getNext(n);
}
return n == 1;
}
private int getNext(int n) {
int totalSum = 0;
while (n > 0) {
int d = n % 10;
n = n / 10;
totalSum += d * d;
}
return totalSum;
}
/**
* 官方快慢指针法:核心还是监测是否有环如果有环那么快的一定可以和慢的相遇
* 速度击败100%
* @param n
* @return
*/
public boolean isHappy2(int n) {
int slowRunner = n;
int fastRunner = getNext(n);
while (fastRunner != 1 && slowRunner != fastRunner) {
slowRunner = getNext(slowRunner);
fastRunner = getNext(getNext(fastRunner));
}
return fastRunner == 1;
}
}

View File

@ -19,7 +19,7 @@ import java.util.HashMap;
* @Version: 1.0 * @Version: 1.0
*/ */
public class TwoSum { public class T04_TwoSum {
@Test @Test
public void test(){ public void test(){

View File

@ -19,7 +19,7 @@ import java.util.HashSet;
* 2) nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0 * 2) nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0
* @Version: 1.0 * @Version: 1.0
*/ */
public class FourSumCount { public class T05_FourSumCount {
@Test @Test

View File

@ -0,0 +1,66 @@
package com.markilue.leecode.hashtable.second;
import org.junit.Test;
/**
*@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.hashtable.second
*@Author: dingjiawen
*@CreateTime: 2022-12-27 10:01
*@Description:
* TODO 二刷242题 有效的字母异位词:
* 给定两个字符串 s t 编写一个函数来判断 t 是否是 s 的字母异位词
* 注意 s t 中每个字符出现的次数都相同则称 s t 互为字母异位词
*@Version: 1.0
*/
public class T01_IsAnagram {
@Test
public void test(){
String s = "anagram";
String t = "nagaram";
System.out.println(isAnagram(s,t));
}
@Test
public void test1(){
String s = "rat";
String t = "car";
System.out.println(isAnagram(s,t));
}
/**
* 思路:统计个字符出现的次数再作比较即可
* 由于字符都是小写字母所以可以用数组存
* @param s
* @param t
* @return
*/
public boolean isAnagram(String s, String t) {
int[] sArray = new int[26];
// int[] tArray = new int[26];
char[] chars1 = s.toCharArray();
char[] chars2 = t.toCharArray();
for (int i = 0; i < chars1.length; i++) {
sArray[chars1[i]-'a']++;
}
for (int i = 0; i < chars2.length; i++) {
sArray[chars2[i]-'a']--;
}
for (int i = 0; i < sArray.length; i++) {
if(sArray[i]!=0){
return false;
}
}
return true;
}
}

View File

@ -0,0 +1,90 @@
package com.markilue.leecode.hashtable.second;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
/**
*@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.hashtable.second
*@Author: dingjiawen
*@CreateTime: 2022-12-27 10:45
*@Description:
* TODO 二刷349题 两个数组的交集:
* 给定两个数组 nums1 nums2 返回 它们的交集 输出结果中的每个元素一定是 唯一 我们可以 不考虑输出结果的顺序
*@Version: 1.0
*/
public class T02_Intersection {
@Test
public void test(){
int[] nums1 = {1, 2, 2, 1};
int[] nums2 = {2, 2};
System.out.println(Arrays.toString(intersection(nums1,nums2)));
}
@Test
public void test1(){
int[] nums1 = {4,9,5};
int[] nums2 = {9,4,9,8,4};
System.out.println(Arrays.toString(intersection(nums1,nums2)));
}
/**
* 思路:唯一且不要求顺序:hashset
* 速度击败98.76%内存击败13.48% 1ms
* @param nums1
* @param nums2
* @return
*/
public int[] intersection(int[] nums1, int[] nums2) {
HashSet<Integer> set = new HashSet<>();
for (int i : nums1) {
set.add(i);
}
int size=0;
// int length=Math.max(nums1.length,nums2.length);
int[] result = new int[set.size()];
for (int i : nums2) {
if(set.contains(i)){
result[size++]=i;
set.remove(i);
}
}
return Arrays.copyOf(result,size);
}
/**
* 官方最快使用一个boolean[]来代替hashSet
* 速度击败100%内存击败52.55% 0ms
* @param nums1
* @param nums2
* @return
*/
public int[] intersection1(int[] nums1, int[] nums2) {
boolean[] flag = new boolean[1001];
ArrayList<Integer> integers = new ArrayList<>();
for(int i :nums1){
flag[i] = true;
}
for(int j :nums2){
if(flag[j]){
integers.add(j);
flag[j] = false;
}
}
int[] ints = new int[integers.size()];
for(int i = 0;i<integers.size();i++){
ints[i] = integers.get(i);
}
return ints;
}
}

View File

@ -0,0 +1,68 @@
package com.markilue.leecode.hashtable.second;
import org.junit.Test;
import java.util.Arrays;
import java.util.HashMap;
/**
*@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.hashtable.second
*@Author: dingjiawen
*@CreateTime: 2022-12-27 11:36
*@Description:
* TODO 二刷1题 两数之和:
* 给定一个整数数组 nums 和一个整数目标值 target请你在该数组中找出 和为目标值 target 的那 两个 整数并返回它们的数组下标
* 你可以假设每种输入只会对应一个答案但是数组中同一个元素在答案里不能重复出现
* 你可以按任意顺序返回答案
*@Version: 1.0
*/
public class T04_TwoSum {
@Test
public void test(){
int[] nums = {2, 7, 11, 15};
int target = 9;
System.out.println(Arrays.toString(twoSum(nums,target)));
}
@Test
public void test1(){
int[] nums = {3,2,4};
int target = 6;
System.out.println(Arrays.toString(twoSum(nums,target)));
}
@Test
public void test2(){
int[] nums = {3,3};
int target = 6;
System.out.println(Arrays.toString(twoSum(nums,target)));
}
/**
* 思路这题使用动归法可以本质上就是一个target为9的背包问题但是动归法只能知道能不能凑成target不能知道过程是怎么凑出来的
* 由于只有一种答案可以使用hash法<target-num,num对应的i>
* 速度击败78.74%内存击败14.5%
* @param nums
* @param target
* @return
*/
public int[] twoSum(int[] nums, int target) {
HashMap<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
Integer find = map.getOrDefault( nums[i], -1);
if(find!=-1){
//找到了
return new int[]{find,i};
}else {
map.put(target-nums[i],i);
}
}
return new int[2];
}
}

View File

@ -0,0 +1,142 @@
package com.markilue.leecode.hashtable.second;
import org.junit.Test;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
/**
*@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.hashtable.second
*@Author: dingjiawen
*@CreateTime: 2022-12-27 12:10
*@Description:
* TODO 二刷454题 四数相加 II
* 给你四个整数数组 nums1nums2nums3 nums4 数组长度都是 n 请你计算有多少个元组 (i, j, k, l) 能满足
* 0 <= i, j, k, l < n
* nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0
*@Version: 1.0
*/
public class T05_FourSumCount {
@Test
public void test(){
int[] nums1 = {1, 2}, nums2 = {-2, -1}, nums3 = {-1, 2}, nums4 = {0, 2};
System.out.println(fourSumCount(nums1,nums2,nums3,nums4));
}
@Test
public void test1(){
int[] nums1 = {0}, nums2 = {0}, nums3 = {0}, nums4 = {0};
System.out.println(fourSumCount(nums1,nums2,nums3,nums4));
}
/**
* 思路:这题求得是组合数而不要求里面到底是那四个index,
* 考虑两个nums两两组成map<sum,count>
* 速度击败62.9%内存击败24.56% 143%
* @param nums1
* @param nums2
* @param nums3
* @param nums4
* @return
*/
public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
HashMap<Integer, Integer> map = new HashMap<>();
for (int i : nums1) {
for (int i1 : nums2) {
map.put(i+i1,map.getOrDefault(i+i1,0)+1);
}
}
HashMap<Integer, Integer> map1 = new HashMap<>();
for (int i : nums3) {
for (int i1 : nums4) {
map1.put(i+i1,map1.getOrDefault(i+i1,0)+1);
}
}
int result=0;
for (Integer integer : map.keySet()) {
result+=map1.getOrDefault(-integer,0)*map.get(integer);
}
return result;
}
/**
* 官方hash解法比本人少用一次hashmap直接在for循环里面加即可
* 速度击败82.48%内存击败5.1%
* @param A
* @param B
* @param C
* @param D
* @return
*/
public int fourSumCount1(int[] A, int[] B, int[] C, int[] D) {
Map<Integer, Integer> countAB = new HashMap<Integer, Integer>();
for (int u : A) {
for (int v : B) {
countAB.put(u + v, countAB.getOrDefault(u + v, 0) + 1);
}
}
int ans = 0;
for (int u : C) {
for (int v : D) {
if (countAB.containsKey(-u - v)) {
ans += countAB.get(-u - v);
}
}
}
return ans;
}
/**
* 官方题解中最快的解法:
* 速度击败99.95%内存击败10.31% 47ms
* @param nums1
* @param nums2
* @param nums3
* @param nums4
* @return
*/
public int fourSumCount2(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
Arrays.sort(nums1);
Arrays.sort(nums2);
Arrays.sort(nums3);
Arrays.sort(nums4);
int resultCounter = 0;
Map<Integer, Integer> numMap = new HashMap<>();
for (int i = 0; i < nums1.length; i++) {
int iStart = i;
//重复就加快循环
while (i + 1 < nums1.length && nums1[i] == nums1[i + 1]) {
i++;
}
for (int j = 0; j < nums2.length; j++) {
int jStart = j;
while (j + 1 < nums2.length && nums2[j] == nums2[j + 1]) {
j++;
}
numMap.put(nums1[i] + nums2[j], numMap.getOrDefault(nums1[i] + nums2[j], 0) + (i-iStart+1) * (j-jStart+1));
}
}
for (int i = 0; i < nums3.length; i++) {
int iStart = i;
while (i + 1 < nums3.length && nums3[i] == nums3[i + 1]) {
i++;
}
for (int j = 0; j < nums4.length; j++) {
int jStart = j;
while (j + 1 < nums4.length && nums4[j] == nums4[j + 1]) {
j++;
}
resultCounter += numMap.getOrDefault(-nums3[i]-nums4[j], 0) * (i - iStart + 1) * (j - jStart + 1);
}
}
return resultCounter;
}
}