(B卷,200分)- 书籍叠放(Java & JS & Python)

题目描述

书籍的长、宽都是整数对应 (l,w)。如果书A的长宽度都比B长宽大时,则允许将B排列放在A上面。现在有一组规格的书籍,书籍叠放时要求书籍不能做旋转,请计算最多能有多少个规格书籍能叠放在一起。

输入描述

输入:books = [[20,16],[15,11],[10,10],[9,10]]

说明:总共4本书籍,第一本长度为20宽度为16;第二本书长度为15宽度为11,依次类推,最后一本书长度为9宽度为10.

输出描述

输出:3

说明: 最多3个规格的书籍可以叠放到一起, 从下到上依次为: [20,16],[15,11],[10,10]

用例

输入 [[20,16],[15,11],[10,10],[9,10]]
输出 3

题目解析

本题就是

可以采用耐心排序+二分查找,实现O(nlgn)时间复杂度的算法。

具体解题思路请看上面博客。

Java算法源码

import java.util.*;

public class Main {
  public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);

    String input = sc.nextLine();

    // (?<=]),(?=[) 正则表达式含义是:找这样一个逗号,前面跟着],后面跟着[
    // 其中(?<=) 表示前面跟着
    // 其中(?=) 表示后面跟着
    Integer[][] books =
        Arrays.stream(input.substring(1, input.length() - 1).split("(?<=]),(?=\[)"))
            .map(
                s ->
                    Arrays.stream(s.substring(1, s.length() - 1).split(","))
                        .map(Integer::parseInt)
                        .toArray(Integer[]::new))
            .toArray(Integer[][]::new);

    System.out.println(getResult(books));
  }

  public static int getResult(Integer[][] books) {
    // 长度升序,若长度相同,则宽度降序
    Arrays.sort(books, (a, b) -> Objects.equals(a[0], b[0]) ? b[1] - a[1] : a[0] - b[0]);
    Integer[] widths = Arrays.stream(books).map(book -> book[1]).toArray(Integer[]::new);
    return getMaxLIS(widths);
  }

  // 最长递增子序列
  public static int getMaxLIS(Integer[] nums) {
    //  dp数组元素dp[i]含义是:长度为i+1的最优子序列的尾数
    ArrayList<Integer> dp = new ArrayList<>();
    dp.add(nums[0]);

    for (int i = 1; i < nums.length; i++) {
      if (nums[i] > dp.get(dp.size() - 1)) {
        dp.add(nums[i]);
        continue;
      }

      if (nums[i] < dp.get(0)) {
        dp.set(0, nums[i]);
        continue;
      }

      int idx = Collections.binarySearch(dp, nums[i]);
      if (idx < 0) dp.set(-idx - 1, nums[i]);
    }

    return dp.size();
  }
}

JavaScript算法源码

/* JavaScript Node ACM模式 控制台输入获取 */
const readline = require("readline");

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});

rl.on("line", (line) => {
  const books = JSON.parse(line);
  console.log(getMaxStackCount(books));
});

function getMaxStackCount(books) {
  // 长度升序,若长度相同,则宽度降序
  const widths = books
    .sort((a, b) => (a[0] === b[0] ? b[1] - a[1] : a[0] - b[0]))
    .map((book) => book[1]);

  return getMaxLIS(widths);
}

// 最长递增子序列
function getMaxLIS(nums) {
  // dp数组元素dp[i]含义是:长度为i+1的最优子序列的尾数
  const dp = [nums[0]];

  for (let i = 1; i < nums.length; i++) {
    if (nums[i] > dp[dp.length - 1]) {
      dp.push(nums[i]);
      continue;
    }

    if (nums[i] < dp[0]) {
      dp[0] = nums[i];
      continue;
    }

    const idx = binarySearch(dp, nums[i]);
    if (idx < 0) dp[-idx - 1] = nums[i];
  }

  return dp.length;
}

// 二分查找
function binarySearch(arr, key) {
  let low = 0;
  let high = arr.length - 1;

  while (low <= high) {
    let mid = (low + high) >>> 1;
    let midVal = arr[mid];

    if (key > midVal) {
      low = mid + 1;
    } else if (key < midVal) {
      high = mid - 1;
    } else {
      return mid;
    }
  }
  return -(low + 1);
}

Python算法源码

# 输入获取
books = eval(input())


# 二分查找
def binarySearch(arr, key):
    low = 0
    high = len(arr) - 1

    while low <= high:
        mid = (low + high) >> 1
        midVal = arr[mid]

        if key > midVal:
            low = mid + 1
        elif key < midVal:
            high = mid - 1
        else:
            return mid

    return -(low + 1)


# 最长递增子序列
def getMaxLIS(nums):
    # dp数组元素dp[i]含义是:长度为i+1的最优子序列的尾数
    dp = [nums[0]]

    for i in range(1, len(nums)):
        if nums[i] > dp[-1]:
            dp.append(nums[i])
            continue

        if nums[i] < dp[0]:
            dp[0] = nums[i]
            continue

        idx = binarySearch(dp, nums[i])
        if idx < 0:
            dp[-idx - 1] = nums[i]

    return len(dp)


# 算法入口
def getResult(books):
    # 长度升序,若长度相同,则宽度降序
    books.sort(key=lambda x: (x[0], -x[1]))
    widths = list(map(lambda x: x[1], books))
    return getMaxLIS(widths)


# 算法调用
print(getResult(books))

 

免责声明:

1、IT资源小站为非营利性网站,全站所有资料仅供网友个人学习使用,禁止商用
2、本站所有文档、视频、书籍等资料均由网友分享,本站只负责收集不承担任何技术及版权问题
3、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除下载链接并致以最深的歉意
4、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
5、一经注册为本站会员,一律视为同意网站规定,本站管理员及版主有权禁止违规用户
6、其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和IT资源小站的同意
7、IT资源小站管理员和版主有权不事先通知发贴者而删除本文

0

评论0

站点公告

没有账号?注册  忘记密码?