[LeetCode] HashMap题目总结

本文总结了LeetCode中涉及HashMap的题目,包括Two Sum、Longest Substring Without Repeating Characters、Valid Sudoku等,详细解释了如何利用HashMap解决这类问题,如使用滑动窗口、存储字符映射和频率等策略。
摘要由CSDN通过智能技术生成

1. Two Sum

找出数组中加起来等于target的两个数。每一个输入有且仅有一个解,但是同一个元素不能使用两次。
可以使用HashMap + 单遍循环,key为数组中的元素,value为下标。如果hashmap中已经存储过target - nums[i]了,那么就找到了一对结果。如果没有存储过target - nums[i],那么就将(nums[i] , i)放入HashMap。

class Solution {
   
    public int[] twoSum(int[] nums, int target) {
   
        HashMap<Integer, Integer> map = new HashMap<>();//key:number   Value:index
        int [] ans = new int [2];
        
        for(int i = 0; i < nums.length; i++){
   
            if(map.containsKey(target - nums[i])){
   
                ans[0] = map.get(target - nums[i]);
                ans[1] = i;
                break;
            }
            map.put(nums[i], i);
        }
        return ans;
    }
}

3. Longest Substring Without Repeating Characters

给定一个字符串,找出最长的没有重复字符的子串。

滑动窗口+HashMap。HashMap的key是出现的字符,value是该字符的下标。right指针向右移动时,如果发现HashMap已经有了right指向的字符,那么说明该字符重复了,而该字符的位置正是该字符在HashMap中的value值。于是可以直接将left指针移动到该字符的下一位置。

class Solution {
   
    public int lengthOfLongestSubstring(String s) {
   
        char [] arr = s.toCharArray();
        int left = 0;
        int right = 0;
        int ans = 0;
        HashMap<Character,Integer> map = new HashMap<>();
        
        for(; right < arr.length; right++){
   
            if(map.containsKey(arr[right])){
   
                left = Math.max(left, map.get(arr[right])+1);
            }
            ans = Math.max(ans, right - left +1);
            map.put(arr[right], right);
        }
        return ans;
    }
}

30. Substring with Concatenation of All Words

给定一个字符串s,和一个单词列表words,words中的每个词长度相等。需要在s中寻找,包含全部词,且每个词只出现一次,没有任何多余其他字符的子串。

本题使用HashMap来存储words中的词。key是词,value是该词在words中出现次数。
words中每个词的长度都是一样的,我们可以假设每个词的长度为length,而一共有n个词,所以满足要求的子串必然是长度为 n * length 的子串
于是我们遍历每一个长度为 n * length的子串,子串也有自己的HashMap,如果子串的某一个词在words的HashMap中没有,或者这个词在子串中出现的次数大于words的HashMap,那么这个子串就不符合要求。当遍历完整个字串之后,如果这个子串没有break掉,那就是一个正确的解。

class Solution {
   
    public List<Integer> findSubstring(String s, String[] words) {
   
        List<Integer> ans = new ArrayList<>();
        if(s == null || s.length() == 0 || words == null || words.length==0){
   
            return ans;
        }
        
        int numOfWords = words.length;
        int lenOneWord = words[0].length();
        int len = numOfWords * lenOneWord;
        
        HashMap<String, Integer> map = new HashMap<>();
        for(String str: words){
   
            map.put(str, map.getOrDefault(str,0)+1);
        }
        
        for(int i = 0 ; i <= s.length() - len;i++){
   
            HashMap<String, Integer> strCount = new HashMap<>();
            int j = 0;
            for(; j < numOfWords; j++){
   
                String subs = s.substring(i+j*lenOneWord, i+(j+1)*lenOneWord);
                if(!map.containsKey(subs)){
   
                    break;
                }
                strCount.put(subs , strCount.getOrDefault(subs, 0)+1 );
                if(strCount.get(subs) > map.get(subs)){
   
                    break;
                }
            }
            if(j == numOfWords){
   
                ans.add(i);
            }
        }
        return ans;
    }
}

36. Valid Sudoku

判断一个 9x9 的数独是否有效。只需要根据以下规则,验证已经填入的数字是否有效即可。
1 . 数字 1-9 在每一行只能出现一次。
2 . 数字 1-9 在每一列只能出现一次。
3 . 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。

做法很简单,为每一行每一列每一个3x3宫都建一个HashMap,这题可真HashMap。
HashMap也可以用一个长度为9的数组替代。

class Solution {
   
    public boolean isValidSudoku(char[][] board) {
   
        HashMap<Character, Integer> rows[] = new HashMap [9];
        HashMap<Character, Integer> columns[] = new HashMap[9];
        HashMap<Character, Integer> box[] = new HashMap[9];
        for(int i = 0; i <9; i++){
   
            rows[i] = new HashMap<Character, Integer>();
            columns[i] = new HashMap<Character, Integer>();
            box[i] = new HashMap<Character, Integer>();
        }
        
        for(int i = 0; i < 9; i++){
   
            for(int j = 0; j <9; j++){
   
                if(board[i][j] == '.'){
   
                    continue;
                }
                rows[i].put(board[i][j] , rows[i].getOrDefault(board[i][j], 0) + 1);
                columns[j].put(board[i][j] , columns[j].getOrDefault(board[i][j], 0) + 1);
    
                int numOfBox = (i/3) * 3 + (j/3);
                box[numOfBox].put(board[i][j] , box[numOfBox].getOrDefault(board[i][j], 0) + 1);
                
                if(rows[i].get(board[i][j]) >1 || 
                   columns[j].get(board[i][j]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值