算法训练营(第一期)第三天(java)
学习感悟:
1,我不应该被事物的表象所威慑,我应当不断告诉自己这个道理:随着不断的学习,思考我对于一些问题或事情的认识会逐渐的变清晰.例如有些问题我一开始感觉特别的难特别的复杂,完全没有头绪.但是当我一遍遍的思考,一点点深入,我对其的认知会一点点建立起来.
题目
一、两个数组的交集(leetcode349)
题目
错误解法
import java.util.HashSet;
class Solution {
public int[] intersection(int[] nums1, int[] nums2) {
//若是使用双层循环也不好做因为要保证连续,当我判断前面出现连续时若是后面也出现连续那么我怎么表达,但别的我也没啥思路其实不是我理解错题意了我把此题理解为字符串匹配了
//由于元素较多用数组不太方便那么我就用hashset.
HashSet<Integer> Hash1=new HashSet<>();
HashSet<Integer> Hash2=new HashSet<>();
int count=0;
for(int i=0;i<nums1.length;i++){
Hash1.add(nums1[i]);
}
//若是采用数组装填的话有个问题就是不能去重
for(int j=0;j<nums2.length;j++){
if(Hash1.contains(nums2[j])){
count++;
}
}
int[] a=new int[count];
count=0;
for(int j=0;j<nums2.length;j++){
if(Hash1.contains(nums2[j])){
a[count++]=nums2[j];
}
}
return a;
}
}
正确解法
import java.util.HashSet;
class Solution {
public int[] intersection(int[] nums1, int[] nums2) {
//若是使用双层循环也不好做因为要保证连续,当我判断前面出现连续时若是后面也出现连续那么我怎么表达,但别的我也没啥思路其实不是我理解错题意了我把此题理解为字符串匹配了
//由于元素较多用数组不太方便那么我就用hashset.
HashSet<Integer> Hash1=new HashSet<>();
HashSet<Integer> Hash2=new HashSet<>();
for(int i=0;i<nums1.length;i++){
Hash1.add(nums1[i]);
}
//若是采用数组装填的话有个问题就是不能去重
for(int j=0;j<nums2.length;j++){
if(Hash1.contains(nums2[j])){
Hash2.add(nums2[j]);
}
}
//过两天会补充java8的一些新的特性,我刚开始就是因为不懂这个新特性就尝试用int来存储
return Hash2.stream().mapToInt(x -> x).toArray();
}
}
二、快乐数(leetcode202)
class Solution {
public boolean isHappy(int n) {
//结束的关键在在于循环,只要出现循环即可判定不是快乐数
HashSet<Integer> hs=new HashSet<>();
//我大胆假设只有当x最后为10,1,100,1000时才有可能会出现快乐数,但是我怎么结束这个运算呢?我也不能判定下一步是否为快乐数
//因为要使得进入的值不断变化那不妨写个函数
int x=n;
while(x!=1&& !hs.contains(x)){
hs.add(x);
x=chuLi(x);
}
//返回n==1即可
return x==1;
}
//写一个处理的函数
int chuLi(int x){
int sum=0;
while(x!=0){
int m=x%10;
sum+=m*m;
x=x/10;
}
return sum;
}
}
三、两数之和
题目
一般解法:
class Solution {
public int[] twoSum(int[] nums, int target) {
//如果使用hashset我有个问题就是我怎么确定下标呢,而且出现33这样的例子我又该怎么处理(我可以先遍历一边hashset如果没有这个结果再遍历一边数组即可可以将时间复杂度降为n但是下标怎么处理)
//双层循环解决问题
int[] a={0,0};
for(int i=0;i<nums.length;i++){
for(int j=0;j!=i&&j<nums.length;j++){
if(nums[i]+nums[j]==target) {
a[0]=i;
a[1]=j;
return a;
}
}
}
return a;
}
}
更优解法:
class Solution {
public int[] twoSum(int[] nums, int target) {
//元素是否存在过,使用hashmap,将已经遍历过的元素存入其中,用target减去当前的值再判断是否存在于hashmap中若存在则说明两个元素均存在.而在hashmap中可以用下标当做value,值当做key.
int[] a={0,0};
HashMap<Integer,Integer> Hm=new HashMap();
for(int i=0;i<nums.length;i++){
if(Hm.containsKey(target-nums[i])){
a[0]=Hm.get(target-nums[i]);
a[1]=i;
return a;
}
Hm.put(nums[i],i);
}
return null;
}
}