①、有效的字母异味词
给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词。
力扣(LeetCode)链接:https://leetcode.cn/problems/valid-anagram
事例:
输入: s = "anagram", t = "nagaram" 输出: true
思路:
①、将两字符串转化为数组,排序后比较,若全程相等,则互为字母异位词,若不是,则不互为字母异位词。
public boolean isAnagrma(String s,String t){
int n = s.length();
int m = t.length();
if(n != m){
return false;
}
char[] arr1 = s.toCharArray();
char[] arr2 = t.toCharArray();
Arrays.sort(arr1);
Arrays.sort(arr2);
return Arrays.equals(arr1,arr2);
}
②、借助HashMap,由于字符串中可能存在重复字符,而hashset不能重复,故需要map中的value值存储字符出现的次数,先遍历字符串s存各字符以及出现的次数,再遍历字符串t,若出现对应value值为0(即s中没有出现或消耗完的字符),则返回false,若能完全遍历完,则两字符串为字母异位词。
public boolean isAnagram(String s,String t){
int n = s.length();
int m = t.length();
if(n != m){
return false;
}
char[] arr1 = s.toCharArray();
char[] arr2 = t.toCharArray();
HashMap<Character,Integer> map = new HashMap<>();
//存放s的字符
for(int i = 0;i < n;i++){
char c = arr1[i];
int count = map.getOrDefault(c,0);
map.put(c,count + 1);
}
//验证t
for(int i = 0;i < n;i++){
char c = arr2[i];
int count = map.getOrDefault(c,0);
if(count <= 0){
//不匹配
return false;
}
map.put(c,count - 1);
}
return true;
}
③、创建一个辅助数组,索引值代表字符(0-25代表'a' - 'z'),其中的值代表出现的次数,遍历两个字符串,s中出现字符a,则0索引上的值加加,t则相反,出现则减减,一次循环过后,该数组中的值代表两个字符串各字符出现的差值,即某索引上为正则s多,为负则t多,只有辅助数组上的值全为0,则这两字符串为字母异位词。
public boolean isAnagram(String s,String t){
int n = s.length();
int m = t.length();
if(n != m){
return false;
}
int[] res = new int[26];
for(int i = 0;i < n;i++){
int index1 = s.charAt(i) - 'a';
int index2 = t.charAt(i) - 'a';
res[index1]++;
res[index2]--;
}
for(int i = 0;i < 26;i++){
if(res[i] != 0){
return false;
}
}
return true;
}
②、两个数组的交集
给定两个数组
nums1
和nums2
,返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。
事例:
输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4] 输出:[9,4] 解释:[4,9] 也是可通过的
力扣(LeetCode)链接:https://leetcode.cn/problems/intersection-of-two-arrays/
思路:
①、使用两个set,第一次先遍历num1,将数值存入set1,第二次遍历nums2,若set1中存在(contains方法),则存入set2中。两次遍历结束后,set2中即是答案,再将set2中的值存入结果数组返回即可。
ps:由于set中不允许重复,故不用担心数字重复的情况。
public int[] interSection(int[] nums1,int nums2[]){
if(nums1 == null || nums2 == null) return null;
HashSet<Integer> set = new HashSet<>();
HashSet<Integer> res = 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])){
res.add(nums2[i]);
}
}
int[] resArr = new int[res.size()];
int count = 0;
for(int i : res){
resArr[count++] = i;
}
return resArr;
}
②、创建一个map,map中存放Integer和Boolean,第一次先遍历nums1,每次放入数值和TRUE,(Boolean用来标识,TRUE表示数值出现,false表示没有出现)。第二次遍历nums2,通过key取出value,若value为true,则存放在数组tmp中,再将value设为false(避免数组重复元素),最终将数组tmp中的有效长度复制到结果数组res中,返回即可。
public int[] interSection(int[] nums1,int[] num2){
if(nums1 == null || nums2 == null) return null;
HashMap<Integer,Boolean> map = new HashMap<>();
for(int i = 0;i < nums1.length;i++){
map.put(nums1[i],true);
}
int n = Math.min(nums1.length,nums2.length);
int[] tmp = new int[n];
int count = 0; //记录有多少个交集
for(int i = 0;i < nums2.length;i++){
if(map.getOrDefault(nums2[i],false)){
//说明已经存过
tmp[count++] = nums2[i];
map.put(nums2[i],false);
}
}
int[] res = new int[count];
for(int i = 0;i < count;i++){
//赋值 删除多的数.
res[i] = tmp[i];
}
return res;
}
③、快乐数
编写一个算法来判断一个数 n 是不是快乐数。
「快乐数」 定义为:
对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
如果这个过程 结果为 1,那么这个数就是快乐数。
如果 n 是 快乐数 就返回 true ;不是,则返回 false 。
力扣(LeetCode)链接:https://leetcode.cn/problems/happy-number
事例:
输入:n = 19 输出:true 解释: 1*1 + 9*9 = 82 8*8 + 2*2 = 68 6*6 + 8*8 = 100 1*1 + 0*0 + 0*0 = 1
思路:
该题目的重点在于解析判定快乐数的临界点,如果该数是快乐数的话,则它每位的平方和最终会变为1,但如果不是快乐数的话,则会无限循环;当该数的求每位的平方和的过程中出现重复数字,则会陷入无限循环,故无限循环的临界点为重复数值。可以用set记录每次的每位平方和,若重复则直接判定为非快乐数。
public boolean isHappy(int n) {
HashSet<Integer> set = new HashSet<>();
while(n != 1){
set.add(n);
n = sum(n);
if(set.contains(n)){
return false;
}
}
return true;
}
public int sum(int n){
int res = 0;
while(n > 0){
int tmp = (n % 10) * (n % 10);
res += tmp;
n /= 10;
}
return res;
}
④、两数之和
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
力扣(LeetCode)链接:https://leetcode.cn/problems/two-sum
事例:
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
思路:
①、暴力枚举,用两层for循环,分别判断两个数的和是否为target。
public int[] twoSum(int[] nums,int target){
int[] res = new int[2];
for(int i = 0;i < nums.length - 1;i++){
for(int j = i + 1;j < nums.length;j++){
if((nums[i] + nums[j]) == target){
res[0] = i;
res[1] = j;
break;
}
}
}
return res;
}
②、通过HashMap记录出现过的值以及对应的下标,判断map是否存在target - nums[i],若为TRUE,则表示这两个数即要所求的两个数。
public int[] twoSum(int[] nums,int target){
Map<Integer,Integer> map = new HashMap<>();
for(int i = 0;i < nums.length;i++){
if(map.containsKey(target - nums[i])){
//已找到组合
return new int[]{map.get(target - nums[i]),i};
}else{
map.put(nums[i],i);
}
}
return null;
}