代码随想录算法训练营 day 6: 242.有效的字母异位词 | 349. 两个数组的交集 | 202. 快乐数 | 1. 两数之和

80 阅读1分钟

242. Valid Anagram Given two strings s and t, return true if t is an anagram of s , and false otherwise.

An Anagram is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once.

  • 1 <= s.length, t.length <= 5 * 104
  • s and t consist of lowercase English letters.

这题用自定义的字符map来做,原题只包含小写英文字母。所以取值区间只有26个。定义一个26元素数组即可。 在follow up里问到若是包含unicode该怎么样做,那肯定不适合用自定义字符map了,Unicode取值区间太大,那就只能用Map来做,以字符值为key,出现的次数为value,生成两个map然后比较。若是相同,则为Anagram,否则不是。

代码:

class Solution {

    public boolean isAnagram(String s, String t) {
        int[] mmap = new int[26];

        if(s.length() != t.length()) {
            return false;
        }

        for(int i=0; i<s.length(); i++) {
            mmap[s.charAt(i) - 'a']++;
            mmap[t.charAt(i) - 'a']--;
        }

        for(int i=0; i<26; i++) {
            if(mmap[i] != 0) {
                return false;
            }
        }

        return true;

    }
}

349. Intersection of Two Arrays Given two integer arrays nums1 and nums2, return an array of their intersection. Each element in the result must be unique and you may return the result in any order. Constraints:

  • 1 <= nums1.length, nums2.length <= 1000
  • 0 <= nums1[i], nums2[i] <= 1000

求两数组重合的元素集合,且要求集合内没有重复元素。这就很明显了,使用set。 先扫数组1,生成set1,然后扫数组2,对每个元素判断是否存在于set1,存在的,写入结果集合。 结果不定长,先写到一个set里,最后再转为数组返回。

代码:

class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
        if(nums1 == null || nums1.length == 0 || nums2 == null || nums2.length == 0) {
            return new int[0];
        }
        Set<Integer> set1 = new HashSet<Integer>();
        Set<Integer> set2 = new HashSet<Integer>();

        for(int i=0; i<nums1.length; i++) {
            set1.add(nums1[i]);
        }
        
        for(int i=0; i< nums2.length; i++) {
            if(set1.contains(nums2[i])) {
                set2.add(nums2[i]);
            }
        }

        return set2.stream().mapToInt(x->x).toArray();

    }
}

202. Happy Number

Write an algorithm to determine if a number n is happy.

happy number is a number defined by the following process:

  • Starting with any positive integer, replace the number by the sum of the squares of its digits.
  • Repeat the process until the number equals 1 (where it will stay), or it loops endlessly in a cycle which does not include 1.
  • Those numbers for which this process ends in 1 are happy.

Return true if n is a happy number, and false if not.

 

Example 1:

Input: n = 19
Output: true
Explanation:
12 + 92 = 82
82 + 22 = 68
62 + 82 = 100
12 + 02 + 02 = 1

Example 2:

Input: n = 2
Output: false

 

Constraints:

  • 1 <= n <= 231 - 1

这题要想清楚。每次需要将input数分解为个位数,这需要一个while循环和一个数组来存放,注意不能为set,会滤掉重复的数字。 分解为个位数后,算出数组内元素平方的和 sum。 如果sum为1,则返回true。 如果sum不为1,则将sum存放于set内。每次需检查sum是否存在于set,若存在,则意味着进入了死循环。 将sum作为下一循环的input。但考虑到下一循环需要重新计算sum,所以加入一个prev记录本循环的sum,并将sum清零以便下个循环使用。下个循环需要将prev做个位数分解,然后计算sum。

代码:

class Solution {
    public boolean isHappy(int n) {
        Set<Integer> set2 = new HashSet<Integer>();

        int val = n;
        List<Integer> l1 = new ArrayList<Integer>();
        while(val > 0) {
            l1.add(val % 10);
            val = val / 10;
        }

        int sum = 0;
        int prev = 0;

        while(sum >= 0 && sum <= Integer.MAX_VALUE && sum != 1)  {
            while(prev > 0) {
                l1.add(prev % 10);
                prev = prev / 10;
            }            
            for (int i: l1) {
                sum += (i * i);
            }
            if(sum == 1) {
                return true;
            }
            else if (set2.contains(sum)) {
                return false;
            }
            else {
                prev = sum;
                set2.add(sum);
                sum = 0;
                l1.clear();
            }
        }

        return false;
    }
}

1. Two Sum Given an array of integers nums and an integer target, return indices of the two numbers such that they add up to target.

You may assume that each input would have exactly one solution, and you may not use the same element twice.

You can return the answer in any order.

 

Example 1:

Input: nums = [2,7,11,15], target = 9
Output: [0,1]
Explanation: Because nums[0] + nums[1] == 9, we return [0, 1].

Example 2:

Input: nums = [3,2,4], target = 6
Output: [1,2]

Example 3:

Input: nums = [3,3], target = 6
Output: [0,1]

 

Constraints:

  • 2 <= nums.length <= 104
  • -109 <= nums[i] <= 109
  • -109 <= target <= 109
  • Only one valid answer exists.

目标是O(n)的话,只能扫一遍。扫到每个元素时,将当前元素cur存在一个map里,如果 target - cur也存在与map,则找到答案,返回【cur,map(cur)】。 所以map的value需要存元素下标。如果target - cur不存在于map,则将当前元素cur写入map,value为当前index

本题其实有四个重点:

  • 为什么会想到用哈希表
  • 哈希表为什么用map
  • 本题map是用来存什么的
  • map中的key和value用来存什么的

代码:

class Solution {
    public int[] twoSum(int[] nums, int target) {
        int[] res = new int[2];
        if(nums.length == 0) {
            return new int[0];
        }

        Map<Integer, Integer> mmap = new HashMap<Integer, Integer>();

        for(int i=0; i<nums.length; i++) {
            int left = target - nums[i];

            if(mmap.containsKey(nums[i])) {
                return new int[]{i, mmap.get(nums[i])};
            }
            else {

                mmap.put(left, i);
            }
        }

        return new int[0];
    }
}