day05 1. 两数之和&&第202题. 快乐数&&349. 两个数组的交集&&242.有效的字母异位词

  1. 两数之和(Two Sum)
    问题描述:
    给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下标。
    解决方案:
    暴力法:使用两层嵌套循环,遍历所有可能的数对,检查它们的和是否等于目标值。时间复杂度为 O(n^2)。
    哈希表法:使用哈希表存储每个元素的值和索引。遍历数组时,检查 target - nums[i] 是否已经在哈希表中。如果存在,返回这两个索引。时间复杂度为 O(n)。
    //1. 两数之和
    public int[] twoSum(int[] nums, int target) {
    //暴力法
    /int[] result = new int[2];
    for (int i = 0; i < nums.length; i++) {
    for (int j = i + 1; j < nums.length; j++) {
    if (nums[i] + nums[j] == target) {
    result[0] = i;
    result[1] = j;
    }
    }
    }
    return result;
    /
    HashMap<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 new int[]{};
    }

  2. 快乐数(Happy Number)
    问题描述:
    编写一个算法来判断一个数是不是“快乐数”。
    从一个正整数开始,每次将该数替换为它每个位上的数字的平方和。
    然后重复这个过程直到这个数变为 1,也可能是无限循环但始终变不到 1。
    如果这个过程结束时,这个数变为 1,那么这个数就是快乐数。
    解决方案:
    哈希集合法:使用一个集合记录已经出现过的数,避免无限循环。如果某个数再次出现,说明进入了循环,返回 false。如果某个数变为 1,返回 true。
    快慢指针法:使用两个指针,一个快一个慢,快指针每次走两步,慢指针每次走一步。如果存在循环,快慢指针最终会相遇。如果某个数变为 1,返回 true。
    //第202题. 快乐数
    public boolean isHappy(int n) {
    Set set = new HashSet<>();
    while (true){
    int sum = 0;
    while (n > 0) {
    int temp = n % 10;
    sum += temptemp;
    n = n / 10;
    }
    if(sum==1){
    return true;
    }else {
    if(set.contains(sum)){
    return false;
    }else {
    set.add(sum);
    n=sum;
    }
    }
    }
    /
    //快慢指针法,效率更高
    public int getNext(int n) {
    int totalSum = 0;
    while (n > 0) {
    int d = n % 10;
    n = n / 10;
    totalSum += d * d;
    }
    return totalSum;
    }

     public boolean isHappy(int n) {
         int slowRunner = n;
         int fastRunner = getNext(n);
         //无限循环则快慢指针的值会相等
         while (fastRunner != 1 && slowRunner != fastRunner) {
             slowRunner = getNext(slowRunner);
             fastRunner = getNext(getNext(fastRunner));
         }
         return fastRunner == 1;*/
    

    }

  3. 两个数组的交集(Intersection of Two Arrays)
    问题描述:
    给定两个数组,编写一个函数返回它们的交集。
    解决方案:
    排序法:先对两个数组进行排序,然后使用双指针遍历两个数组,找到相同的元素并添加到结果集合中。最后将集合转换为数组。
    哈希集合法:使用两个集合分别存储两个数组的元素,然后遍历其中一个集合,检查元素是否在另一个集合中。如果在,添加到结果集合中。最后将集合转换为数组。
    代码:
    //349. 两个数组的交集
    public int[] intersection(int[] nums1, int[] nums2) {
    /*Stream.toArray()
    *功能
    该方法将流中的元素收集到一个 Object[] 数组中。
    返回的数组类型是 Object[],数组中的每个元素都是流中的一个元素。
    *Stream.toArray(Generator<T[]> generator)
    *当你需要特定类型的数组(如 Integer[]、String[] 等)时,可以使用这个方法。
    * stream().mapToInt(Integer::intValue).toArray()
    * 如果是先转成基本数据类型再存储到数组中,就不用在roArray()中传参
    * /
    Arrays.sort(nums1);
    Arrays.sort(nums2);
    Set set = new HashSet<>();
    int i = 0, j = 0;
    while (i < nums1.length && j < nums2.length) {
    if (nums1[i] == nums2[j]) {
    set.add(nums1[i]);
    i++;
    j++;
    } else if (nums1[i] < nums2[j]) {
    i++;
    } else {
    j++;
    }
    }
    //.mapToInt(Integer::intValue),直接用数组接收比使用流效率高
    return set.stream().mapToInt(Integer::intValue).toArray();
    /

    //少了sort排序,效率高一点。直接用数组按哈希法处理效率会更高,但是不具备普适性
    Set set1 = new HashSet<>();
    Set set2 = new HashSet<>();

     for(int num:nums1){
         set1.add(num);
     }
    
     for(int num:nums2){
         if(set1.contains(num)){
             set2.add(num);
         }
     }
    
     int[] result = new int[set2.size()];
     int index  = 0;
     for(int num:set2){
         result[index++]=num;
     }
     return result;*/
    

    }

  4. 有效的字母异位词(Valid Anagram)
    问题描述:
    给定两个字符串 s 和 t,编写一个函数判断它们是否是字母异位词。
    解决方案:
    哈希表法:使用两个哈希表分别记录两个字符串中每个字符的出现次数,然后比较两个哈希表是否相等。
    计数法:使用一个长度为 26 的数组记录每个字符的出现次数。遍历字符串 s 时,增加对应字符的计数;遍历字符串 t 时,减少对应字符的计数。最后检查数组中的所有计数是否为 0。
    //242.有效的字母异位词
    public boolean isAnagram(String s, String t) {
    /char[] s1 = s.toCharArray();
    char[] t1 = t.toCharArray();
    Map<Character, Integer> map1 = new HashMap<>();
    Map<Character, Integer> map2 = new HashMap<>();
    for (char c : s1) {
    map1.put(c, map1.getOrDefault(c, 0) + 1);
    }
    for (char c : t1) {
    map2.put(c, map2.getOrDefault(c, 0) + 1);
    }
    return map1.equals(map2);
    /
    //不具备普适性,toCharArray()遍历字符串字符比charAt()遍历字符串中字符效率高,增强for比普通for效率高
    int[] s1 = new int[26];
    int[] t1 = new int[26];
    for (char c : s.toCharArray()) {
    s1[c - 'a']++;
    }
    for (char c : t.toCharArray()) {
    t1[c - 'a']++;
    }
    for (int i = 0; i < 26; i++) {
    if (s1[i] != t1[i]) {
    return false;
    }
    }
    return true;
    }

posted @ 2025-01-19 01:48  123木头人-10086  阅读(108)  评论(0)    收藏  举报