IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 2021-10-26:给定一个数组arr,arr[i] = j,表示第i号试题的难度为j。给定一个非负数M。想出一张卷子,对于任何相邻的两道题目,前一题的难度不能超过后一题的难度+M。返回所有可能的卷 -> 正文阅读

[数据结构与算法]2021-10-26:给定一个数组arr,arr[i] = j,表示第i号试题的难度为j。给定一个非负数M。想出一张卷子,对于任何相邻的两道题目,前一题的难度不能超过后一题的难度+M。返回所有可能的卷

2021-10-26:给定一个数组arr,arr[i] = j,表示第i号试题的难度为j。给定一个非负数M。想出一张卷子,对于任何相邻的两道题目,前一题的难度不能超过后一题的难度+M。返回所有可能的卷子种数。

答案2021-10-26:

方法1:递归。纯暴力方法,生成所有排列,一个一个验证。
方法2:从左往右的动态规划 + 范围上二分。时间复杂度O(N * logN)。
方法3:从左往右的动态规划 + IndexTree。时间复杂度O(N * logV)。

代码用golang编写。代码如下:

package main

import (
    "fmt"
    "math"
    "sort"
)

func main() {
    if true {
        arr := []int{1, 5, 3, 4, 2}
        ret := ways1(arr, 3)
        fmt.Println(ret)
    }
    if true {
        arr := []int{1, 5, 3, 4, 2}
        ret := ways2(arr, 3)
        fmt.Println(ret)
    }
    if true {
        arr := []int{1, 5, 3, 4, 2}
        ret := ways3(arr, 3)
        fmt.Println(ret)
    }

}

// 纯暴力方法,生成所有排列,一个一个验证
func ways1(arr []int, m int) int {
    if len(arr) == 0 {
        return 0
    }
    return process(arr, 0, m)
}

func process(arr []int, index int, m int) int {
    if index == len(arr) {
        for i := 1; i < index; i++ {
            if arr[i-1] > arr[i]+m {
                return 0
            }
        }
        return 1
    }
    ans := 0
    for i := index; i < len(arr); i++ {
        arr[index], arr[i] = arr[i], arr[index]
        ans += process(arr, index+1, m)
        arr[index], arr[i] = arr[i], arr[index]
    }
    return ans
}

// 时间复杂度O(N * logN)
// 从左往右的动态规划 + 范围上二分
func ways2(arr []int, m int) int {
    if len(arr) == 0 {
        return 0
    }
    //Arrays.sort(arr);
    sort.Ints(arr)
    all := 1
    for i := 1; i < len(arr); i++ {
        all = all * (num(arr, i-1, arr[i]-m) + 1)
    }
    return all
}

// arr[0..r]上返回>=t的数有几个, 二分的方法
// 找到 >=t 最左的位置a, 然后返回r - a + 1就是个数
func num(arr []int, r int, t int) int {
    i := 0
    j := r
    m := 0
    a := r + 1
    for i <= j {
        m = (i + j) / 2
        if arr[m] >= t {
            a = m
            j = m - 1
        } else {
            i = m + 1
        }
    }
    return r - a + 1
}

// 时间复杂度O(N * logV)
// 从左往右的动态规划 + IndexTree
func ways3(arr []int, m int) int {
    if len(arr) == 0 {
        return 0
    }
    max := math.MinInt64
    min := math.MaxInt64
    for _, num := range arr {
        max = getMax(max, num)
        min = getMin(min, num)
    }
    itree := NewIndexTree(max - min + 2)
    //Arrays.sort(arr);
    sort.Ints(arr)
    a := 0
    b := 0
    all := 1
    itree.add(arr[0]-min+1, 1)
    for i := 1; i < len(arr); i++ {
        a = arr[i] - min + 1
        if a-m-1 >= 1 {
            b = i - itree.sum(a-m-1)
        } else {
            b = i
        }
        //b = i - (a - m - 1 >= 1 ? itree.sum(a - m - 1) : 0);
        all = all * (b + 1)
        itree.add(a, 1)
    }
    return all
}

func getMax(a, b int) int {
    if a > b {
        return a
    } else {
        return b
    }
}

func getMin(a, b int) int {
    if a < b {
        return a
    } else {
        return b
    }
}

// 注意开始下标是1,不是0
type IndexTree struct {
    tree []int
    N    int
}

func NewIndexTree(size int) *IndexTree {
    res := &IndexTree{}
    res.N = size
    res.tree = make([]int, size+1)
    return res
}

func (this *IndexTree) sum(index int) int {
    ret := 0
    for index > 0 {
        ret += this.tree[index]
        index -= index & -index
    }
    return ret
}

func (this *IndexTree) add(index, d int) {
    for index <= this.N {
        this.tree[index] += d
        index += index & -index
    }
}

执行结果如下:
图片


左神java代码

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-10-27 13:04:40  更:2021-10-27 13:05:50 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 8:21:08-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码