用这样的方法,我解决了leetcode的大部分的这种题型!

点个赞,看一看,好习惯!本文 GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了 3 个月总结的一线大厂 Java 面试总结,本人已拿腾讯等大厂 offer。
另外,原创文章首发在我的个人博客:blog.ouyangsihai.cn,欢迎访问。

今天介绍一种解决常规的贪心策略或者字典排序的题目的通用解题方法。

第一题,leetcode中等难度题目

先来一道简单的字典序排列的问题,这个题目我这里不会用最优解来解决这个问题,这个是leetcode的中等难度的题目,最优解还是需要再思考一下的,这道题目作为文章开头只是为了介绍我想要介绍的贪心的解题的一种思路而已,大佬请勿喷!!

看到这个题目,我就是想用暴力的方法解决,以便更好的理解这种解题思路。

先给出我的答案,非常暴力,但是非常好理解。

public List<Integer> lexicalOrder(int n) {
        List<String> list = new ArrayList<>();
        for(int i = 1; i <= n; i++){
            list.add(i + "");
        }
        Collections.sort(list,(o1,o2)->{
            return o1.compareTo(o2);
        });
        List<Integer> iList = new ArrayList<>();
        list.stream().forEach((str)->{
            iList.add(Integer.parseInt(str));
        });
        return iList;
    }

这个解题方法很简单,用的就是Collections.sort()方法的排序,然后重写一下Comparator类而已,这里用的是lambda表达式,使得代码更加的简洁

最优解大家可以去leetcode看看哈,自己动手,丰衣足食。

所以,通过这个题目我想给出的信息就是:通常涉及到字符串排序,字典序,数字排序等等的题目,都是可以用这种思路来解决问题的

不信,我们再看看其他题目。

第二题,leetcode中等难度题目

这是一道常见的topk问题,最优解也不是我给出的答案,目的只是为了阐述这种解题方法。

我的解题方法:用优先级队列,维护一个大小为k小顶堆,每次堆的元素到达k时,先弹出堆顶元素,这样就堆总是维持着k个最大值,最终可以的到前k高的元素。

下面看看我的解答(注意:我的答案绝对不是最优解,只是为了阐述这种方法)

class Solution {
    public int[] topKFrequent(int[] nums, int k) {
        Queue<Obj> queue = new PriorityQueue<>(k,(o1,o2)->{
            return o2.num - o1.num;
        });

        HashMap<Integer,Integer> map = new HashMap<>();

        for(int i = 0; i < nums.length; i++){
            map.put(nums[i],map.getOrDefault(nums[i],0) + 1);
        }

        for(int key : map.keySet()){
            queue.offer(new Obj(key,map.get(key)));
        }

        int[] ans = new int[k];
        int i = 0;
        while(i < k){
            ans[i] = queue.poll().target;
            i++;
        }

        return ans;

    }

    class Obj {
        public int target;
        public int num;

        public Obj(int target, int num){
            this.target = target;
            this.num = num;
        }
    }
}

这种方法没有维护k的最大的堆。

class Solution {
  public List<Integer> topKFrequent(int[] nums, int k) {
    HashMap<Integer, Integer> map = new HashMap();
    for (int n: nums) {
      map.put(n, map.getOrDefault(n, 0) + 1);
    }

    PriorityQueue<Integer> heap =
            new PriorityQueue<Integer>((n1, n2) -> map.get(n1) - map.get(n2));


    for (int n: map.keySet()) {
      heap.add(n);
      if (heap.size() > k)
        heap.poll();
    }
    
    List<Integer> top_k = new LinkedList();
    while (!heap.isEmpty())
      top_k.add(heap.poll());
    Collections.reverse(top_k);
    return top_k;
  }
}

这种方法维护k的最大的堆。

对比发现:不管维护k的最大堆还是不维护,核心的思想都是

Queue<Obj> queue = new PriorityQueue<>(k,(o1,o2)->{
            return o2.num - o1.num;
        });

和这段代码

PriorityQueue<Integer> heap =
            new PriorityQueue<Integer>((n1, n2) -> map.get(n1) - map.get(n2));

对比第一题中的

Collections.sort(list,(o1,o2)->{
            return o1.compareTo(o2);
        });

用的都是内部类:Comparator,然后进行构建符合题意的排序规则

第三题,更复杂点的

这个题目就更能明白什么是构建符合题意的排序规则

因为很多题目不止让你根据一个字段进行排序,可能是两个字段进行排序,或者三个字段进行排序,所以就需要进行“构建”。

这个题目的解题思路:先排序再插入

  • 排序规则:按照先H高度降序,K个数升序排序
  • 遍历排序后的数组,根据K插入到K的位置上

核心思想:高个子先站好位,矮个子插入到K位置上,前面肯定有K个高个子,矮个子再插到前面也满足K的要求。

再看看解答

public int[][] reconstructQueue(int[][] people) {
        // [7,0], [7,1], [6,1], [5,0], [5,2], [4,4]
        // 再一个一个插入过程
        // [7,0]
        // [7,0], [7,1]
        // [7,0], [6,1], [7,1]
        // [5,0], [7,0], [6,1], [7,1]
        // [5,0], [7,0], [5,2], [6,1], [7,1]
        // [5,0], [7,0], [5,2], [6,1], [4,4], [7,1]
        Arrays.sort(people, (o1, o2) -> o1[0] == o2[0] ? o1[1] - o2[1] : o2[0] - o1[0]);

        LinkedList<int[]> list = new LinkedList<>();
        for (int[] i : people) {
            //在i位置,插入数:i[1]是[7,0], [7,1], [6,1], [5,0], [5,2], [4,4]的第一个数,表示前面有几个比我高的。
            list.add(i[1], i);
        }

        return list.toArray(new int[list.size()][2]);
    }

你会发现,核心代码还是跟第一题和第二题一样,只是复杂一点点。

Arrays.sort(people, (o1, o2) -> o1[0] == o2[0] ? o1[1] - o2[1] : o2[0] - o1[0]);

这是什么意思呢:o1和o2是一个类似这样[7,0]的一位数组,当第一个数相等时,再比较一维数组的第二个数的大小,不相等,当然先比较第一个数了。

这个就是多个字段比较的例子,是不是还是跟前面的思路是一样的。

总结

最后发现,关于排序的,不管是,数组的排序,数字的排序,字符串的排序,还是优先级队列的排序,我们都是可以用Java的Comparator来解决的。

就说这么多,只是思路,不要死磕最优解!!!

最后,再分享我历时三个月总结的 Java 面试 + Java 后端技术学习指南,这是本人这几年及春招的总结,已经拿到了大厂 offer,整理成了一本电子书,拿去不谢,目录如下:

现在免费分享大家,在下面我的公众号 程序员的技术圈子 回复 面试 即可获取。

有收获?希望老铁们来个三连击,给更多的人看到这篇文章

1、老铁们,关注我的原创微信公众号「程序员的技术圈子」,专注于 Java、数据结构和算法、微服务、中间件等技术分享,保证你看完有所收获。

2、给俺点个赞呗,可以让更多的人看到这篇文章,顺便激励下我继续写作,嘻嘻。

3、另外,原创文章首发在我的个人博客:blog.ouyangsihai.cn,欢迎访问。

点赞是对我最大的鼓励
↓↓↓↓↓↓

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,230评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,261评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,089评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,542评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,542评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,544评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,922评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,578评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,816评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,576评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,658评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,359评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,937评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,920评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,859评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,381评论 2 342