1、快乐数
题目链接:https://leetcode.cn/problems/happy-number/description/
我们可以看到如果有循环的话,直接就输出false就行,那么当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法了。
方法一:哈希表
package com.cky.lianbiao;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
public class RemoveEle {
public static boolean isHappy(int n) {
Set<Integer> hash=new HashSet<>();
while(n!=1&&!hash.contains(n)){
hash.add(n);
n=square(n);
}
return n==1;
}
public static int square(int n){
int res=0;
while(n>0){
int temp=n%10;
res+=temp*temp;
n=n/10;
}
return res;
}
public static void main(String[] args) {
System.out.println(isHappy(2));
}
}
方法二:快慢指针
因为如果有循环的话,会有一个隐形的圆环。
①如果快慢指针相遇了则代表有循环,则直接false
②如果是快乐数,则快指针一定会比慢指针首先到达1
比如 (不用管数值 瞎写的)如果1在偶数则快指针直接遇到了第一个,快指针先到达
这种情况下还是快指针先到达
package com.cky.lianbiao;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
public class RemoveEle {
public static boolean isHappy(int n) {
int slow=n;
int fast=square(n);
while(fast!=1&&fast!=slow){
slow=square(slow);
fast=square(square(fast));
}
return fast==1;
}
public static int square(int n){
int res=0;
while(n>0){
int temp=n%10;
res+=temp*temp;
n=n/10;
}
return res;
}
public static void main(String[] args) {
System.out.println(isHappy(19));
}
}
2、三数之和
题目:
https://leetcode.cn/problems/3sum/description/
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
int n =nums.length;
Arrays.sort(nums);
for(int first=0;first<n;first++){
// 排序之后如果第一个元素已经大于零,那么无论如何组合都不可能凑成三元组,直接返回结果就可以了
if (nums[first] > 0) {
return result;
}
if(first>0 && nums[first]==nums[first-1]){
continue;
}
int third=n-1;
int sum=-nums[first];
for(int second=first+1;second<n;second++){
if(second>first+1 && nums[second]==nums[second-1]){
continue;
}
while(second<third&&nums[second]+nums[third]>sum){
third--;
}
if(second==third)
break;
if(third<n-1&&nums[third]==nums[third+1])
third--;
if(nums[second]+nums[third]==sum){
result.add(Arrays.asList(nums[first], nums[second], nums[third]));
}
}
}
return result;
}
}
本题用哈希表来解决会比较困难,原因是去重比较复杂,注意这里的去重不是说元素之间的去重 比如[-1,-1,2],而是说不能有两个一样的结果。
首先 我们会考虑三重循环 但是三重循环复杂度 O(n3),那么能否考虑一个相对来说不耗时的呢,就是第二步,去重,对第一个,第二重,第三重都进行去重,如果和原来的一样,就跳过,但是这样子复杂度仍然不变。
接着就是第三步考虑,去掉一个循环,因为第一个循环确定第一个数,第二个循环确定第二个数,那么第三个数,其实可以不用循环,从最右边开始,(但是这要先对数组进行排序)。
3、四树之和
其实和三树之和一样,只不过多了一层循环。
‘https://leetcode.cn/problems/4sum/description/
class Solution {
public List<List<Integer>> fourSum(int[] nums,int target) {
List<List<Integer>> result = new ArrayList<>();
int n =nums.length;
Arrays.sort(nums);
if (nums == null || nums.length < 4) {
return result;
}
for(int first=0;first<n;first++){
if(first>0 && nums[first]==nums[first-1]){
continue;
}
for(int second=first+1;second<n;second++){
if(second>first+1 && nums[second]==nums[second-1]){
continue;
}
long sum=target-((long)nums[first]+nums[second]);
int four=n-1;
for(int third=second+1;third<n;third++){
if(third>second+1 && nums[third]==nums[third-1]){
continue;
}
while(third<four&&((long)nums[third]+nums[four])>sum){
four--;
}
if(third==four)
break;
if(four<n-1&&nums[four]==nums[four+1])
four--;
if((long)nums[third]+nums[four]==sum){
result.add(Arrays.asList(nums[first], nums[second], nums[third],nums[four]));
}
}
}}
return result;
}
}
4、两数之和
这个可以用哈希表,因为没有去重,并且需要返回索引。
https://leetcode.cn/problems/two-sum/description/
class Solution {
public int[] twoSum(int[] nums, int target) {
int[] indexs=new int[2];
Map<Integer,Integer> map=new HashMap<Integer,Integer>();
for(int i=0;i<nums.length;i++){
if(map.containsKey(target-nums[i])){
indexs[0]=map.get(target-nums[i]);
indexs[1]=i;
break;
}
map.put(nums[i],i);
}
return indexs;
}
}