当前位置: 首页 > news >正文

Day 26:哈希 + 双指针

49. 字母异位词分组 - 力扣(LeetCode)

一开始出错,使用了List作为键,但是List都是不一样的。

class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        HashMap<List<Character>, List<String>> map = new HashMap<>();

        for(int i = 0; i < strs.length; i++){
            List<Character> list = new LinkedList<>();
            for(int j = 0; j < strs[i].length(); j++){
                list.add(strs[i].charAt(j));
            }
            if(map.containsKey(list) == false){
                List<String> str = new LinkedList<>();
                str.add(strs[i]);
                map.put(list, str);
            } else {
                map.get(list).add(strs[i]);
            }      
        }

        List<List<String>> res = new LinkedList<>();

        Set<List<Character>> keys = map.keySet();
        for (List<Character> list : keys) {
            res.add(map.get(list));
        }

        return res;
    }
}

解决方法:修改键值为String。

class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        HashMap<String, List<String>> map = new HashMap<>();

        for(int i = 0; i < strs.length; i++){
            char[] chars = strs[i].toCharArray();
            Arrays.sort(chars);
            String key = new String(chars);

            if(map.containsKey(key) == false){
                List<String> str = new LinkedList<>();
                str.add(strs[i]);
                map.put(key, str);
            } else {
                map.get(key).add(strs[i]);
            }      
        }

        List<List<String>> res = new LinkedList<>();

        Set<String> keys = map.keySet();
        for (String s : keys) {
            res.add(map.get(s));
        }

        return res;
    }
}

没想到这么简单一个题目拖了这么久。而且哈希里的很多操作并不熟悉。

128. 最长连续序列 - 力扣(LeetCode)

一开始想着排序做,时间复杂度O(nlogn)但是这是在哈希表里面的题目。

用哈希表记录数据,遍历哈希表,如果存在后一位数,就++,不断更新最大长度。

class Solution {
    public int longestConsecutive(int[] nums) {
        int max = 0;
        HashSet<Integer> set = new HashSet<>();
        for(int i = 0; i < nums.length; i++){
            set.add(nums[i]);
        }

        for(int num : set){
            if(!set.contains(num - 1)){
                int currentNum = num;
                int currentLength = 1;
                while(set.contains(currentNum + 1)){
                    currentLength++;
                    currentNum++;
                }

                max = Math.max(max, currentLength);
            } 
        }
        return max;
    }
}

11. 盛最多水的容器 - 力扣(LeetCode)

双指针题目

class Solution {
    public int maxArea(int[] height) {
        int l = 0;
        int r = height.length - 1;
        int max = 0;
        while(l < r){
            
            max = Math.max(max,Math.min(height[l],height[r])*(r - l));

            if(height[l] < height[r]){
                l++;
            } else {
                r--;
            }
            
        }

        return max;
    }
}

有一点贪心的思想,用while简化了两个for循环,因为我们每次都取更长的板,那种可能会让结果更小的可能性我们就不考虑了。从而降低复杂度。

15. 三数之和 - 力扣(LeetCode)

暴力写就是查找,会超时

改成二分查找降低时间复杂度:

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> res = new ArrayList<>();
        Arrays.sort(nums);
        for(int i = 0; i < nums.length; i ++){
            if (i > 0 && nums[i] == nums[i - 1]) continue; // 外层去重
            int l = i + 1;
            int r = nums.length - 1;
            int target = -nums[i];

            while(l < r){
                int sum = nums[l] + nums[r];
                if(target == sum){
                    res.add(Arrays.asList(nums[i], nums[l], nums[r]));
                    l++;
                    r--;
                } else if (sum < target) {
                    l++;
                } else {
                    r--;
                }
            }   
        }

        return res;
    }
}

但是还要去重:

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> res = new ArrayList<>();
        Arrays.sort(nums);
        for(int i = 0; i < nums.length; i ++){
            if (i > 0 && nums[i] == nums[i - 1]) continue; // 外层去重
            int l = i + 1;
            int r = nums.length - 1;
            int target = -nums[i];

            while(l < r){
                int sum = nums[l] + nums[r];
                if(target == sum){
                    res.add(Arrays.asList(nums[i], nums[l], nums[r]));
                    while(l < r && nums[l] == nums[l + 1]) l++;
                    while(l < r && nums[r] == nums[r - 1]) r--;
                    l++;
                    r--;
                } else if (sum < target) {
                    l++;
                } else {
                    r--;
                }
            }   
        }

        return res;
    }
}

42. 接雨水 - 力扣(LeetCode)

这一题是盛水容器的高级版本,建议下一次遇到还是用双指针做,动态规划需要维护正向遍历和反向遍历两个数组,短时间内是想不出来的。

首先我们要记住,我们需要分别向左向右遍历。

对于单向的遍历,那向左遍历举例,我们假设右边有一个很高的柱子能把水留住,那么能接住多少水只取决于左边的最大值。 res = res + (l_max - l);  右边同理。

我们就两边的l r指针各自遍历,直到他们遇到。因为取决于的是更小的柱子,跟盛水不一样,盛水取决于高的柱子。所以就相当于在l和r遇到的地方有一个很高的柱子,但是它不会比l_max和r_max小。因为我们是移动l和r里更矮的指针,他们最后会在接雨水最高的的地方重合。

class Solution {
    public int trap(int[] height) {
        int l = 0;
        int r = height.length - 1;
        int left_max = 0, right_max = 0;
        int result = 0;
        while(l < r){
            //移动较矮一侧的指针
            if(height[l] < height[r]){
                if(left_max < height[l]){
                    left_max = height[l];
                } else{
                    result = result + (left_max - height[l]);//我们假设右边有一个很高的柱子
                }
                l++;
            } else{
                if(right_max < height[r]){
                    right_max = height[r];
                } else{
                    result = result + (right_max - height[r]);//我们假设右边有一个很高的柱子
                }
                r--;
            }
        }

        return result;

    }
}

相关文章:

  • 网站二级域名怎么做友情链接出售
  • 网站开发外包项目网站成都seo的方法
  • it外包公司招聘seo 首页
  • 专业网站建设基本流程做网络销售如何找客户
  • 游戏开发和网站开发哪个好玩本地网络seo公司
  • 网站右侧浮动怎么做seo
  • 『Linux』 第十一章 线程同步与互斥
  • 零基础上手Python数据分析 (10):DataFrame 数据索引与选取
  • 滤波---概览
  • [Lc5_dfs+floodfill] 简介 | 图像渲染 | 岛屿数量
  • tomcat部署项目打开是404?
  • 人工智能之数学基础:基于正交变换将矩阵对角化
  • JavaScript 中的闭包及其应用
  • 【零基础入门unity游戏开发——通用篇】SpriteEditor图片编辑器
  • 【CF】Day19——Codeforces Round 904 (Div. 2) C
  • 八股总结(Java)实时更新!
  • Cursor软件设置中文版教程
  • 刷题日记day15-按身高和体重排队
  • swagger问题解决
  • 【常春藤盟校的「社会资本交易所」本质】
  • 什么是Java值传递和引用传递?
  • prism wpf 入门
  • 自动化部署核心概念与实践
  • Redis 哈希表结构详解
  • QtAV入门
  • 两数之和-力扣