【读书笔记:算法小抄】二维递增子序列:信封嵌套问题——Java实现

Java常识

排序基础

  对二维数组或者其他对象进行排序,常用Arrays.sort(T[] a, Comparator<? super T> c)。假如传入的是一个二维数组int[][] arr,那么被比较的对象就是arr[0],arr[1]一类的。
  实现Comparator接口通常需要定义Compare函数,且看Compare函数的文档解释:
  int compare(T o1, T o2)
  Compares its two arguments for order. Returns a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second.
  如果o1的值减去o2的值为负数,说明o1小于o2,为0表示相等,为正数则说明o1大于o2,则o1会被排到o2的后面。通常情况下用o1的值减去o2的值,得到的排序结果为顺序,用o2的值减去o1的值为逆序(因为o2大于o1的时候,得到的是正数,程序会把较小的对象o1放到o2的后面)。

匿名类(Anonymous Classes)

  请先看一段匿名类代码的案例:

public class HelloWorldAnonymousClasses {
  
    interface HelloWorld {
        public void greet();
        public void greetSomeone(String someone);
    }
  
    public void sayHello() {
        
        class EnglishGreeting implements HelloWorld {
            String name = "world";
            public void greet() {
                greetSomeone("world");
            }
            public void greetSomeone(String someone) {
                name = someone;
                System.out.println("Hello " + name);
            }
        }
      
        HelloWorld englishGreeting = new EnglishGreeting();
        
        HelloWorld frenchGreeting = new HelloWorld() {
            String name = "tout le monde";
            public void greet() {
                greetSomeone("tout le monde");
            }
            public void greetSomeone(String someone) {
                name = someone;
                System.out.println("Salut " + name);
            }
        };
        
        HelloWorld spanishGreeting = new HelloWorld() {
            String name = "mundo";
            public void greet() {
                greetSomeone("mundo");
            }
            public void greetSomeone(String someone) {
                name = someone;
                System.out.println("Hola, " + name);
            }
        };
        englishGreeting.greet();
        frenchGreeting.greetSomeone("Fred");
        spanishGreeting.greet();
    }

    public static void main(String... args) {
        HelloWorldAnonymousClasses myApp =
            new HelloWorldAnonymousClasses();
        myApp.sayHello();
    }            
}

  englishGreeting是引用正常定义的EenglishGreeting类的实例,而frenchGreeting变量引用的是匿名类的实例,该匿名类实现了接口HelloWorld的两个方法成员greet和greetSomeone,同时定义了自己的属性成员name。

简介

  二维递增子序列:信封嵌套问题 给出一些信封,每个信封用宽度和高度的整数对形式(w, h)表示。当一个信封A的宽度和高度都比另一个信封B大的时候,则B就可以放进A里,如同“俄罗斯套娃”一样,请计算最多有多少个信封能组成一组“俄罗斯套娃”信封。
  比如输入envelopes = [[5, 4], [6, 4], [6, 7], [2, 3]],算法返回3,因为最多有3个信封能够套起来,它们是[2, 3] => [5, 4] => [6, 7]。

代码

package com.company;
import javax.swing.*;

import static java.lang.System.out;
import java.util.*;

public class Main {
    // 先定义一维的最长子序列求解函数
    public static int lengthOfLIS(int[] nums){
        int[] dp = new int[nums.length];
        Arrays.fill(dp, 1);

        for (int i = 0; i < nums.length; i++) {
            for (int j = 0; j < i; j++) {
                if (nums[j] < nums[i]){
                    dp[i] = Math.max(dp[i], dp[j] + 1);
                }
            }
        }

        int res = 0;
        for (int i = 0; i < dp.length; i++) {
            res = Math.max(res, dp[i]);
        }

        return res;
    }

    // 再进行二维的求解
    public static int maxEnvelopes(int[][] envelopes){
        int n = envelopes.length;
        Arrays.sort(envelopes, new Comparator<int[]>() {
            @Override
            public int compare(int[] o1, int[] o2) {
                // 假设o1对象[5, 4],o2对象为[6, 4],先判断
                // o1和o2的宽度是否相等,若一样再按照高度降序排列
                // 此处o1[0]为5,o1[1]为4,o2[0]为6,o2[1]为4
                return o1[0] == o2[0] ?
                        o2[1] - o2[1] : o1[0] - o2[0];
            }
        });

        // 对高度数组寻找最长子序列LIS
        int[] height = new int[n];
        for (int i = 0; i < n; i++) {
            height[i] = envelopes[i][1];  // 先赋初值
        }

        return lengthOfLIS(height);  // 求解返回
    }

    public static void main(String[] args) {
        int[][] envelopes = {{5, 4}, {6, 4}, {6, 7}, {2, 3}};
        int res = maxEnvelopes(envelopes);
        out.println(res);  // 3
    }
}


参考资料

  • https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html
  • https://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html

如果你认为对你有用,关注我的微信公众号支持我一下吧!~

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱吃柚子的梨

你的鼓励将是我创作的最大动力~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值