Leetcode(Hash)

1.the sum of two nums

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

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

1.3You can return the answer in any order.

Follow-up: Can you come up with an algorithm that is less than O(n2) time complexity?

Method1:

class Solution {
    public int[] twoSum(int[] nums, int target) {
        int[] result=new int[2];//the result data
        for(int i=0;i<nums.length;i++){  
            for(int j=i;j<nums.length;j++){
                if(nums[i]+nums[j]==target){
                    if(i!=j){  //judging if the index is the same
                        result[0]=i;
                        result[1]=j;
                    }
                }
            }
        }
        return result;
    }
}

Method 2: Hash table

It is noted that the time complexity of method 1 is high because the time complexity of finding target - x is too high. Therefore, we need a better way to quickly find out if there is a target element in the array. If it exists, we need to find out its index.

Using a hash table, you can reduce the time complexity of finding target - x to O(N) from O(N) to O(1).

So we create a hash table, and for each x, we first query the hash table for target-x, and then insert x into the hash table to make sure that x doesn't match us.

class Solution {
    public int[] twoSum(int[] nums, int target) {
        int[] re=new int[2];
        //key为数字大小,value是下标
        Map<Integer,Integer> map=new HashMap<>();
        for(int i=0;i<nums.length;i++){
            if(map.containsKey(target-nums[i])){
                return new int[]{i,map.get(target-nums[i])};
            }
            //将当前的数字放入哈希表
            map.put(nums[i],i);
        }
        return new int[0];
    }
}

2. Alphabetic grouping

Method 1: Sorting

Since the two strings containing the same letters, the strings obtained by sorting the two strings must be the same, so the sorted strings can be used as the keys of the hash table.

class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        String temp="";
        if(strs.length==0||strs==null){
            return null;
        }
        char[] chars;
        Map<String,List<String>> map=new HashMap<>();
        for(int i=0;i<strs.length;i++){
            chars=strs[i].toCharArray();
            Arrays.sort(chars);
            temp=new String(chars);
            if(map.get(temp)!=null){
                map.get(temp).add(strs[i]);
            }else{
                List<String> s=new ArrayList<>();
                s.add(strs[i]);
                map.put(temp,s);
            }
        }
        return new ArrayList<List<String>>(map.values());
    }
}

Method 2 (Poor Performance): Counting
Since two strings that are letter heterogeneous words contain the same letters, the number of occurrences of the same letter in the two strings must be the same, so the number of occurrences of each letter can be expressed as a string as the key of the hash table.

class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        if(strs.length==0||strs==null){
            return null;
        }
        Map<String,List<String>> map=new HashMap<>();
        for(int i=0;i<strs.length;i++){
            StringBuilder temp=new StringBuilder(); 
            int[] chars=new int[26];
            int len=strs[i].length();
            for(int j=0;j<len;j++){
                chars[strs[i].charAt(j)-'a']++;
            }
            for(int k=0;k<26;k++){
                if(chars[k]!=0){
                    temp.append((char) 'a'+k);
                    temp.append(chars[k]);
                }
            }
            if(map.get(temp.toString())!=null){
                map.get(temp.toString()).add(strs[i]);
            }else{
                List<String> s=new ArrayList<>();
                s.add(strs[i]);
                map.put(temp.toString(),s);
            }
        }
        return new ArrayList<List<String>>(map.values());
    }
}

3. Longest continuous sequence

Method 1: Use hash + double pointer

A hash table stores data to determine whether adjacent numbers exist, and a double pointer represents the maximum and minimum values of a continuous sequence of current numbers, respectively

class Solution {
    public int longestConsecutive(int[] nums) {
        Map<Integer,Boolean> map=new HashMap<>();
        for(int i=0;i<nums.length;i++){
            map.put(nums[i],false);
        }
        int max=-1;
        for(int i=0;i<nums.length;i++){
            if(map.get(nums[i])){
                continue;
            }
            int left=nums[i];
            int right=nums[i];
            while(map.containsKey(left-1)){
                map.put(left-1,true);
                left--;
            }
            while(map.containsKey(right+1)){
                map.put(right+1,true);
                right++;
            }
            max=Math.max(max,right-left);
        }
        return max+1;
    }
}

Method 2: Improved hash version

The value of each hash element represents the maximum length of a continuous sequence in the sequence it is currently in

class Solution {
    public int longestConsecutive(int[] nums) {
        Map<Integer,Integer> map=new HashMap<>();
        for(int i=0;i<nums.length;i++){
            if (map.containsKey(nums[i])){
                continue;
            }
            if(map.containsKey(nums[i]-1)&&map.containsKey(nums[i]+1)){
                int temp=map.get(nums[i]-1)+1+map.get(nums[i]+1);
                map.put(nums[i],temp);
                map.put(nums[i]-map.get(nums[i]-1),temp);
                map.put(nums[i]+map.get(nums[i]+1),temp);
            }else if(map.containsKey(nums[i]-1)){
                int temp=map.get(nums[i]-1)+1;
                map.put(nums[i],temp);
                map.put(nums[i]-map.get(nums[i]-1),temp);
            }else if(map.containsKey(nums[i]+1)){
                int temp=map.get(nums[i]+1)+1;
                map.put(nums[i],temp);
                map.put(nums[i]+map.get(nums[i]+1),temp);
            }else{
                map.put(nums[i],1);
            }
        }
        int max=0;
        for (Integer value : map.values()) {
            max=Math.max(max,value);
        }
        return max;
    }
}

Method 3: Official Solution

class Solution {
    public int longestConsecutive(int[] nums) {
        Set<Integer> numSet=new HashSet<>();
        for(int num:nums){
            numSet.add(num);
        }

        int max=0;
        for(int num:numSet){
            if(numSet.contains(num-1)){
                continue;
            }
            int current=num+1;
            int currentLen=1;
            while(numSet.contains(current)){
                current++;
                currentLen++;
            }

            max=Math.max(max,currentLen);
        }

        return max;
    }
}
posted @ 2023-09-13 16:18  PostMan_Zc  阅读(16)  评论(0)    收藏  举报