zoukankan      html  css  js  c++  java
  • 贪心2

    两数之和,三数之和,最接近的三数之和(注意记录最接近的值并更新),四数之和(注意去除重复),四数之和Ⅱ(四个list,分两组,用hashmap存次数)。
    整体思路:排序加双指针。

    leetcode 49.字母异位词分组
    new ArrayList<>()括号内参数是集合对象Collection,set,list都行。

    class Solution {
        public List<List<String>> groupAnagrams(String[] strs) {
            Map<String, ArrayList<String>> map = new HashMap<>();
    
            for (String str: strs) {
                char[] charArray = str.toCharArray();
                Arrays.sort(charArray);
                String strSorted = String.valueOf(charArray);
                if (map.containsKey(strSorted)) {
                    map.get(strSorted).add(str);
                } else {
                    map.put(strSorted, new ArrayList<String>(Arrays.asList(str)));
                }
            }
            List<List<String>> res = new ArrayList<>();
            return new ArrayList(map.values());
    
        }
    }
    

    leetcode149. 直线上最多的点数
    注意点:

    • 长度小于3
    • 重复点
    • 记录斜率,固定一个点,这样曲线就固定了,不用考虑截距
    class Solution {
        public int maxPoints(int[][] points) {
            if (points.length <= 2) {
                return points.length;
            }
            HashMap<String, Integer> map = new HashMap<>();
            int res = 0;
            for (int i = 0; i < points.length; i++) {
                int maxLine = 0;
                int numSame = 1;
                map.put("", 0);
                for (int j = i+1; j < points.length; j++) {
                    String key = "";
                    int numerator = points[i][1] - points[j][1];
                    int denominator = points[i][0] - points[j][0];
    
                    if (numerator == 0 && denominator == 0) {
                        numSame ++;
                    } else if (numerator == 0) {
                        key = "0_1";
                    } else if (denominator == 0){
                        key = "1_0";
                    } else {
                        int positive = (double)numerator/denominator > 0 ? 1:-1;
                        int factor = gcd(Math.abs(numerator), Math.abs(denominator));
                      
                        numerator = Math.abs(numerator) / factor;
                        denominator = Math.abs(denominator) / factor;
                        key = String.valueOf(positive*numerator)+"_"+String.valueOf(denominator); 
                    }
                    if(key != "") {
                        map.put(key, map.getOrDefault(key, 0)+1);
                        if (map.get(key) > maxLine) {
                            maxLine = map.get(key);
                        }
                    }
                    if (maxLine + numSame > res) {
                        res = maxLine + numSame;
                    }
                }
                map.clear();
            }
            return res;
        }
    
        public int gcd(int a, int b) {
            if (a == 0)
                return b;
            if (a > b) {
                return gcd(b, a);
            } else {
                return gcd(b%a, a);
            }
        }
    }
    

    leetcode219. 存在重复元素Ⅱ
    散列表,或者一个先进先出的队列
    leetcode220. 存在重复元素Ⅲ
    桶,[0, t], [t+1, 2t+1],...只要找到有没有在同一个桶的,或者相邻桶内,差别大小在范围内的,有没有可能说一个桶内有两个元素呢?不可能,有相同元素就直接返回了。
    所以桶内的元素一定是最新的窗口内的元素。
    或者使用TreeSet,和Set区别在于,Set是散列表,而TreeSet是有序的,可以方便地查找前后元素。

    class Solution {
        public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
            TreeSet<Long> tset = new TreeSet<>();
            for (int i=0;i<nums.length;i++) {
                Long s = tset.ceiling((long) nums[i]);
                if (s!=null && s-nums[i] <= t)
                    return true;
    
                s = tset.floor((long) nums[i]);
                if (s!=null && nums[i] - s <= t)
                    return true;
                tset.add((long) nums[i]);
                if (i>=k)
                    tset.remove((long) nums[i-k]);
            }
            return false;
        }
    }
    

    leetcode447.回旋镖的数量
    每个点都不一样,枚举+哈希

    class Solution {
        public int numberOfBoomerangs(int[][] points) {
    
            int res = 0;
    
            //O(n^2)
            for(int i = 0; i < points.length;i++){
                Map<Integer, Integer> record = new HashMap<>();
                for(int j = 0; j < points.length; j ++){
                    if( j != i )
                        if(record.containsKey(distance(points[i], points[j]))){
                            record.put(distance(points[i], points[j]),
                                    record.get(distance(points[i], points[j])) + 1);
                        }
                        else
                            record.put(distance(points[i], points[j]), 1);
                }
                for(int k : record.values()){
                    if(k >= 2)//这里其实可以不加这句,因为k=1或k=0,结果都是0,但是加上可以减少一定的计算量。
                        res += k * (k - 1);
                }
                
            }
    
            return res;
        }
    
        private int distance(int[] x, int[] y){
    
            return (x[0] - y[0]) * (x[0] - y[0]) + (x[1] - y[1]) * (x[1] - y[1]);
        }
    }
    
    
  • 相关阅读:
    PHP多条件模糊查询
    纯干货!一款APP从设计稿到切图过程全方位揭秘(转)
    0532. K-diff Pairs in an Array (M)
    0933. Number of Recent Calls (E)
    0139. Word Break (M)
    0713. Subarray Product Less Than K (M)
    0399. Evaluate Division (M)
    0495. Teemo Attacking (M)
    0179. Largest Number (M)
    0389. Find the Difference (E)
  • 原文地址:https://www.cnblogs.com/zuotongbin/p/13580191.html
Copyright © 2011-2022 走看看