给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词。
示例 1:
输入: s = “anagram”, t = “nagaram”
输出: true
示例 2:
输入: s = “rat”, t = “car”
输出: false
提示:
1 <= s.length, t.length <= 5 * 104
s 和 t 仅包含小写字母
一开始想的是用一个map去记录,key存放char,value 存放出现的次数,然后第二次循环的时候进行map的更新操作, 先判断,在进行更新;如果出现了 value的值==0 或者key不存在,就直接返回false【能这么判断的前提是两个字符串长度是相等的】
看题解,用了一个数组记录, 一开始还疑惑java中 charAt(i)-‘a’ 能否直接返回得到一个int值,查阅资料是会进行自动类型转换为int类型的值。
具体思路:
由于全部是小写字母,所以用一个长度为26的数组记录就好了 下标表示字符的位置,比如说0表示a,value就是出现的次数了。思路和上面的差不多,只不过用了一个数组,和HashMap比的优势在哪呢?
引出一个问题:java数组和HashMap的区别,优缺点。(Todo)
hashmap
class Solution {
public boolean isAnagram(String s, String t) {
//key: string 类型 存放出现过的次数
Map<Character,Integer> map=new HashMap<>();
if(s.length()!=t.length()) return false;
int len=s.length();
for(int i=0;i<len;i++){
map.put( s.charAt(i), map.getOrDefault(s.charAt(i),0)+1);
}
//System.out.println(map);
for(int i=0;i<len;i++){
if(map.get(t.charAt(i))==null || map.get(t.charAt(i))==0){
return false;
}
map.put(t.charAt(i),map.get(t.charAt(i))-1);
//System.out.println(map);
}
return true;
}
}
array
class Solution {
public boolean isAnagram(String s, String t) {
//法2 定义一个数组
int [] record=new int[26];
if(s.length()!=t.length()) return false;
int len=s.length();
// for (int i = 0; i < s.length(); i++) {
// record[s.charAt(i) - 'a']++;
// }
for(int i=0;i<s.length();i++){
record[s.charAt(i)-'a']++;
}
for(int i=0;i<len;i++){
if(record[t.charAt(i)-'a']==0){
return false;
}
record[t.charAt(i)-'a']--;
}
return true;
}
}
给定两个数组 nums1 和 nums2 ,返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。
示例 1:
输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2]
示例 2:
输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[9,4]
解释:[4,9] 也是可通过的
好像自己的惯性思维就是用hashMap
自己想到的hashmap:
key:int类型 记录数字,value:bool类型 记录是否出现过 true代表有这个数
遍历第二个数组的时候,通过containsKey判断是否出现过,并且没有被记录下来的。因为记录后会把value设置为false
set
直接用set判断是否出现过重复的数字,结果记录的集合也用set,会进行自动去重,不用再向上面那用做判断了,上面是用一个arrayList去记录结果了,所以是允许出现重复的值的
hashmap
class Solution {
public int[] intersection(int[] nums1, int[] nums2) {
//map key record number nums1
Map<Integer,Boolean> map =new HashMap<>();
for(int i=0;i<nums1.length;i++){
map.put(nums1[i],true);//true 表示这个数 有
}
List<Integer> array=new ArrayList<>();
for(int i=0;i<nums2.length;i++){
if(map.containsKey(nums2[i])&&map.get(nums2[i])){
array.add(nums2[i]);
map.put(nums2[i],false);
}
}
return array.stream().mapToInt(x -> x).toArray();
}
}
set
class Solution {
public int[] intersection(int[] nums1, int[] nums2) {
//map key record number nums1
Set<Integer> set=new HashSet<>();
Set<Integer> resSet = new HashSet<>();
for(int i=0;i<nums1.length;i++){
set.add(nums1[i]);
}
for(int i=0;i<nums2.length;i++){
if(set.contains(nums2[i])){
resSet.add(nums2[i]);
}
}
return resSet.stream().mapToInt(x->x).toArray();
}
}
对jdk 1.8 的stream流的操作还不是很熟悉,需要去补
本文学会的两个操作:
List转数组
array.stream().mapToInt(x -> x).toArray();
Set 转数组
resSet.stream().mapToInt(x->x).toArray();
编写一个算法来判断一个数 n 是不是快乐数。
「快乐数」 定义为:
对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
如果这个过程 结果为 1,那么这个数就是快乐数。
如果 n 是 快乐数 就返回 true ;不是,则返回 false 。
示例 1:
输入:n = 19
输出:true
解释:
12 + 92 = 82
82 + 22 = 68
62 + 82 = 100
12 + 02 + 02 = 1
示例 2:
输入:n = 2
输出:false
提示:
1 <= n <= 231 - 1
1.先会计算一个数的各个位的平方和。
2.循环计算快乐数,如果出现了重复的,且重复的不为1,那么就返回false,如果出现了1,就返回false。同样判断是否重复用set
自己写的时候在循环判断的时候卡住了,正确的流程应该是
while(1){
1.判断set 是否出现1,出现了直接返回true
2.判断n是否重复,
3.set.add
4.对n重新赋值
}
class Solution {
public boolean isHappy(int n) {
//重复出现一个数了 但不是1 就说明不是快乐数了
Set<Integer> set=new HashSet<>();
//n 不是快乐数 并且没有出现过
while(true){
if(n==1) return true;
if(set.contains(n)) return false;
set.add(n);
n=calHappy(n);
}
}
public int calHappy(int n){
//计算快乐数
int sum=0;
while(n!=0){
//提取个位数
int a=n%10;
sum+=a*a;
n/=10;
}
System.out.println(sum);
return sum;
}
}
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
示例 1:
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
示例 2:
输入:nums = [3,2,4], target = 6
输出:[1,2]
示例 3:
输入:nums = [3,3], target = 6
输出:[0,1]
提示:
2 <= nums.length <= 104
-109 <= nums[i] <= 109
-109 <= target <= 109
只会存在一个有效答案
用Map的k v;其中key 记录当前的值所需要的值,value记录下标。
例如:nums = [2,7,11,15], target = 9
遍历到2的时候 key=7,value=0;
7 key=2,value=1;
由以上的特点,在map.put之前 判断 是否存在了配对的情况了,即到7的时候,判断当前的值当中,是否有需要7的。若有====》》获取value 和当前的i(因为题目要求返回下标)。
class Solution {
public int[] twoSum(int[] nums, int target) {
//写一下暴力解法吧 锻炼一下基础代码能力
// int[] res=new int[2];
// for(int i=0;i
// // System.out.println(i);
// for(int j=i+1;j
// // System.out.println(j);
// if(nums[i]+nums[j]==target){
// res[0]=i;
// res[1]=j;
// }
// }
// }
// return res;
//map key value 结构
//key 当前值的下标 value 期待的目标的值 2: 7 0
int[] res=new int[2];
Map<Integer,Integer> map=new HashMap<>();
for(int i=0;i<nums.length;i++){
//如果我是被需要的 比如说到7 的时候
if(map.containsKey(nums[i]))
{
res[0]=map.get(nums[i]);
res[1]=i;
}
map.put(target-nums[i],i);
}
return res;
}
}
找相同,找重复,找目标值的三大数据结构 数组、map、set
今日是四道简单题,除了快乐数判断的地方卡住了,其他基本都AC了,解法还待进一步优化。
需要补的知识点:JDK1.8 Stream,这周要写一篇博客专门记录这个。