给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
思路:这个题可以定义一个26长度的数组,首先用来统计s的字母出现个数(出现一个字母,对应位++),然后跟t中出现字母作比较(出现一个字母,对应位–),最后看数组是否位上全为0即可,我是把这两个字符串排序后比较……,其实是用的库函数,偷懒了
class Solution {
public boolean isAnagram(String s, String t) {
//将s,t转化为Char数组,排序后,再转回string
char[] ss = s.toCharArray();
Arrays.sort(ss);
s = String.valueOf(ss);
char[] tt = t.toCharArray();
Arrays.sort(tt);
t = String.valueOf(tt);
//比较
if(s.equals(t)) return true;
return false;
}
}
题意:给定两个数组,编写一个函数来计算它们的交集。
输出结果中的每个元素一定是唯一的。
我们可以不考虑输出结果的顺序。
思路:
主要注意,1.选定创建数组长度min(l1,l2),和最终的数组长度count
2.set中不会出现重复元素,不需要去重
其他没有啥,本题就是一道练习set性质和常用函数的简单题
class Solution {
public int[] intersection(int[] nums1, int[] nums2) {
//获取nums1,nums2长度并且创建临时数组
int l1 = nums1.length;
int l2 = nums2.length;
int min_len = l1<l2?l1:l2;
int[] result = new int[min_len];
int count = 0;
//将nums1中元素保存到set中
Set set1 = new LinkedHashSet();
for (int i=0;i<l1;i++){
set1.add(nums1[i]);
}
//遍历l2中的每一个元素,查看是否在set中,如果检查到了,在set中移除,并添加到临时数组中
for (int i=0;i<l2;i++){
if (set1.contains(nums2[i])){
result[count] = nums2[i];
count++;
set1.remove(nums2[i]);
}
}
//生成真正的返回数组
int[] res = Arrays.copyOf(result,count);
return res;
}
}
编写一个算法来判断一个数 n 是不是快乐数。
「快乐数」定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。如果 可以变为 1,那么这个数就是快乐数。
如果 n 是快乐数就返回 True ;不是,则返回 False 。
思路:如果一个数要不是快乐数,要不不是快乐数,如果不是就会无限循环,那么只要观测到有循环,就可以确定不是,因此可以一直对这个数进行快乐数判定的操作,并且将结果保存在set中,一旦有一次结果在set中出现,就是循环,就不是快乐数,如果有一次结果变成了1,那就是快乐数,使用这两个条件约束,避免出现死循环的情况
class Solution {
public boolean isHappy(int n) {
Set set = new LinkedHashSet();
while(true){
//快乐数操作
int count = 0;
int tmp = n;
while(tmp!=0){
count += (tmp%10)*(tmp%10);
tmp=tmp/10;
}
//检查结果是否为1和检查结果是否在set中
if (count == 1) return true;
else if(set.contains(count)) return false;
//都不是,则将结果加入到set中
else {
set.add(count);
n = count;
}
}
}
}
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。
思路:两层for循环可以做,但是使用map就是一层for循环 on2变成了on
class Solution {
public int[] twoSum(int[] nums, int target) {
Map<Integer,Integer> map = new HashMap<Integer, Integer>();
for (int i=0;i<nums.length;i++){
//如果key有与该数相加为target的值,则返回
if (map.get(target-nums[i])!=null){
return new int[]{map.get(target-nums[i]),i};
}
//否则,将该位置的值,和位置信息作为key,value传入map中
map.put(nums[i],i);
}
throw new IllegalArgumentException("No two sum solution");
}
}
给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j] + C[k] + D[l] = 0。
「例如:」
输入: A = [ 1, 2] B = [-2,-1] C = [-1, 2] D = [ 0, 2]
输出: 2
「解释:」
两个元组如下:
(0, 0, 0, 1) -> A[0] + B[0] + C[0] + D[1] = 1 + (-2) + (-1) + 2 = 0
(1, 1, 0, 0) -> A[1] + B[1] + C[0] + D[0] = 2 + (-1) + (-1) + 0 = 0
思路:a+b之和作为一个map c+d之和作为一个map,然后对两个map进行比较,得出结果。
用A+B+C作为一个,D单独作为一个也不是不行,但是时间复杂度变为on3,会超时
class Solution {
public int fourSumCount(int[] A, int[] B, int[] C, int[] D) {
int n = A.length;
Map<Integer,Integer> map1 = new HashMap<Integer,Integer>();
//遍历a,b数组,计算所有a[i]+b[j]的和,并把它们以和为key,出现次数为value的形式保存在map中
for (int i=0;i<n;i++){
for (int j=0;j<n;j++){
map1.put(A[i]+B[j],map1.getOrDefault(A[i]+B[j],0)+1);
}
}
Map<Integer,Integer> map2 = new HashMap<Integer,Integer>();
//遍历c,d数组,所做事情同上
for (int i=0;i<n;i++){
for (int j=0;j<n;j++){
map2.put(C[i]+D[j],map2.getOrDefault(C[i]+D[j],0)+1);
}
}
int count = 0;
//遍历map1.看map2中是否有对应和为0的key,若有,计算次数
for (int key:map1.keySet()){
if (map2.get(-key)!=null){
count += map1.get(key) * map2.get(-key);
}
}
return count;
}
}
给定一个赎金信 (ransom) 字符串和一个杂志(magazine)字符串,判断第一个字符串 ransom 能不能由第二个字符串 magazines 里面的字符构成。如果可以构成,返回 true ;否则返回 false。
(题目说明:为了不暴露赎金信字迹,要从杂志上搜索各个需要的字母,组成单词来表达意思。杂志字符串中的每个字符只能在赎金信字符串中使用一次。)
「注意:」
你可以假设两个字符串均只含有小写字母。
canConstruct(“a”, “b”) -> false canConstruct(“aa”, “ab”) -> false canConstruct(“aa”, “aab”) -> true
思路:使用map统计字符串中字符个数,然后比较两个字符串生成的map,看map是否符合逻辑
class Solution {
//使用map统计字符串中字符个数
public static Map<Character,Integer> string2Map(String str){
Map<Character,Integer> map = new HashMap<Character,Integer>();
char[] charArray = str.toCharArray();
for (char c:charArray){
map.put(c,map.getOrDefault(c,0)+1);
}
return map;
}
public boolean canConstruct(String ransomNote, String magazine) {
Map<Character,Integer> map1 = string2Map(ransomNote);
Map<Character,Integer> map2 = string2Map(magazine);
//根据逻辑比较两个map
for (char c:map1.keySet()){
if (map2.get(c)==null || map2.get(c)<map1.get(c)){
return false;
}
}
return true;
}
}