2021-07-30:两个有序数组间相加和的Topk问题。给定两个有序数组arr1和arr2,再给定一个整数k,返回来自arr1和arr2的两个数相加和最大的前k个,两个数必须分别来自两个数组。按照降
2021-07-30:两个有序数组间相加和的Topk问题。给定两个有序数组arr1和arr2,再给定一个整数k,返回来自arr1和arr2的两个数相加和最大的前k个,两个数必须分别来自两个数组。按照降序输出。[要求]时间复杂度为O(klogk)。
福大大 答案2021-07-30:
1.左神方法。大根堆。
时间复杂度:O(klogk)。
空间复杂度:O(k)。
2.我的方法。小根堆。两个有序数组构成一个二维数组。然后从右下往左上遍历,当遍历数量大于等于k时,停止遍历。见图。
时间复杂度:略大于O(k)。
空间复杂度:O(k)。

代码用golang编写。代码如下:
package main
import (
"fmt"
"sort"
)
func main() {
arr1 := []int{1, 2, 3, 4, 5}
arr2 := []int{3, 5, 7, 9, 11}
topK := 4
if true {
ret := topKSum1(arr1, arr2, topK)
fmt.Println("左神的方法:", ret)
}
if true {
ret := topKSum2(arr1, arr2, topK)
fmt.Println("我的方法:", ret)
}
}
type Node struct {
index1 int // arr1中的位置
index2 int // arr2中的位置
sum int // arr1[index1] + arr2[index2]的值
}
func NewNode(i1 int, i2 int, s int) *Node {
ret := &Node{}
ret.index1 = i1
ret.index2 = i2
ret.sum = s
return ret
}
func topKSum1(arr1 []int, arr2 []int, topK int) []int {
if len(arr1) == 0 || len(arr2) == 0 || topK < 1 {
return nil
}
N := len(arr1)
M := len(arr2)
topK = getMin(topK, N*M)
res := make([]int, topK)
resIndex := 0
maxHeap := make([]*Node, 0)
set := make(map[int]struct{})
i1 := N - 1
i2 := M - 1
Push(&maxHeap, NewNode(i1, i2, arr1[i1]+arr2[i2]))
set[x(i1, i2, M)] = struct{}{}
for resIndex != topK {
curNode := Pop(&maxHeap)
res[resIndex] = curNode.sum
resIndex++
i1 = curNode.index1
i2 = curNode.index2
delete(set, x(i1, i2, M))
_, ok := set[x(i1-1, i2, M)]
if i1-1 >= 0 && !ok {
set[x(i1-1, i2, M)] = struct{}{}
Push(&maxHeap, NewNode(i1-1, i2, arr1[i1-1]+arr2[i2]))
}
_, ok = set[x(i1, i2-1, M)]
if i2-1 >= 0 && !ok {
set[x(i1, i2-1, M)] = struct{}{}
Push(&maxHeap, NewNode(i1, i2-1, arr1[i1]+arr2[i2-1]))
}
}
return res
}
func getMin(a int, b int) int {
if a < b {
return a
} else {
return b
}
}
func x(i1 int, i2 int, M int) int {
return i1*M + i2
}
func Push(maxHeap *[]*Node, node *Node) {
*maxHeap = append(*maxHeap, node)
}
func Pop(maxHeap *[]*Node) *Node {
sort.Slice(*maxHeap, func(i, j int) bool {
return (*maxHeap)[i].sum < (*maxHeap)[j].sum
})
ans := (*maxHeap)[len(*maxHeap)-1]
*maxHeap = (*maxHeap)[0 : len(*maxHeap)-1]
return ans
}
func topKSum2(arr1 []int, arr2 []int, topK int) []int {
if len(arr1) == 0 || len(arr2) == 0 || topK < 1 {
return nil
}
N := len(arr1)
M := len(arr2)
topK = getMin(topK, N*M)
maxHeap := make([]int, 0)
i1Start, i2Start := N-1, M-1
count := 0
for {
for i1, i2 := i1Start, i2Start; i1 >= 0 && i2 < M; i1, i2 = i1-1, i2+1 {
PushInt(&maxHeap, arr1[i1]+arr2[i2])
if len(maxHeap) > topK {
PopInt(&maxHeap)
}
count++
}
if count >= topK {
break
}
if i2Start > 0 { //左移
i2Start--
} else { //上移
i1Start--
}
}
return maxHeap
}
func PushInt(maxHeap *[]int, node int) {
*maxHeap = append(*maxHeap, node)
}
func PopInt(maxHeap *[]int) int {
sort.Slice(*maxHeap, func(i, j int) bool {
return (*maxHeap)[i] > (*maxHeap)[j]
})
ans := (*maxHeap)[len(*maxHeap)-1]
*maxHeap = (*maxHeap)[0 : len(*maxHeap)-1]
return ans
}
执行结果如下:

2021-07-30:两个有序数组间相加和的Topk问题。给定两个有序数组arr1和arr2,再给定一个整数k,返回来自arr1和arr2的两个数相加和最大的前k个,两个数必须分别来自两个数组。按照降的更多相关文章
- 两个数组各个数相加或相乘变成一个矩阵求第K大
input 1<=T<=20 1<=n<=100000,1<=k<=n*n a1 a2 ... an 0<ai<=10000 b1 b2 ... bn ...
- 给定两个数组,这两个数组是排序好的,让你求这两个数组合到一起之后第K大的数。
题目:给定两个数组,这两个数组是排序好的,让你求这两个数组合到一起之后第K大的数. 解题思路: 首先取得数组a的中位数a[aMid],然后在b中二分查找a[aMid],得到b[bMid],b[bSt] ...
- 在O(N)时间内求解 正数数组中 两个数相加的 最大值
一,问题描述 给定一个正数数组arr(即数组元素全是正数),找出该数组中,两个元素相加的最大值,其中被加数的下标大于加数的下标.由加法运算的可逆性,j >i 这个条件可以去掉. 即求出: max ...
- 作业帮:给定一个整数数组,找出其中两个数相加等于目标值(去重set)
题目描述 给定一个整数数组,找出其中两个数相加等于目标值 输入 [1,3,5,7,9,11] 10 输出 1,9 3,7 代码: import java.util.HashMap; import ja ...
- 两个序列求前k大和
---恢复内容开始--- 没有题目,没有题意,这是学长提过的一个技巧,给你两个排好序的序列,每次可以各从中取一个,求前k大的和, 一个优先队列,先将a序列中最大的那个和b序列所有元素相加存进队列中,每 ...
- CUDA学习(三)之使用GPU进行两个数相加
在CPU上定义两个数并赋值,然后使用GPU核函数将两个数相加并返回到CPU,在CPU上显示 #include "cuda_runtime.h" #include "dev ...
- 17.从键盘上输入一个正整数n,请按照以下五行杨辉三角形的显示方式, 输出杨辉三角形的前n行。请采用循环控制语句来实现。 (三角形腰上的数为1,其他位置的数为其上一行相邻两个数之和。) 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 10 5 1
17.从键盘上输入一个正整数n,请按照以下五行杨辉三角形的显示方式, 输出杨辉三角形的前n行.请采用循环控制语句来实现. (三角形腰上的数为1,其他位置的数为其上一行相邻两个数之和.) 1 1 1 1 ...
- 【LeetCode-面试算法经典-Java实现】【002-Add Two Numbers (单链表表示的两个数相加)】
[002-Add Two Numbers (单链表表示的两个数相加)] 原题 You are given two linked lists representing two non-negative ...
- 函数bsxfun,两个数组间元素逐个计算的二值操作
转自http://www.cnblogs.com/rong86/p/3559616.html 函数功能:两个数组间元素逐个计算的二值操作 使用方法:C=bsxfun(fun,A,B) 两个数组A合B间 ...
- 牛客网2016.4.11(两个数相加为sum/计数一个int型的二进制有多少个1/二叉树是否左右对称)
求最小的两个数相加为sum //求最小的两个数相加为sum public ArrayList<Integer> FindNumbersWithSum(int [] array,int su ...
随机推荐
- 页面录制服务上线:RESTful API 调用实现,所见所录即所得
我们为很多实时互动场景提供了服务.在一些场景中,用户不仅需要实时互动,还需要把互动的过程录下来.那么一个好的录制解决方案究竟需要具备哪些特征呢? 在回答这个问题之前,先聊一下客户使用录制的原因.一般来 ...
- 如何基于Security框架兼容多套用户密码加密方式
一.说明 当已上线的系统存在使用其他的加密方式加密的密码数据,并且密码 不可逆 时,而新的数据采用了其他的加密方式,则需要同时兼容多种加密方式的密码校验. 例如下列几种情况: 旧系统用户的密码采用了 ...
- 基于DPDK抓包的Suricata安装部署
一.背景 Suricata支持网卡在线抓包和离线读取PCAP包两种形式的抓包: 离线抓包天然具有速度慢.非实时的特点 在线捕获数据包又包括常规网卡抓包.PF_RING和DPDK的方式 由于项目分光的流 ...
- Live Home 3D Pro - 用于公寓和房屋的室内设计,支持 3D 实时渲染
Live Home 3D Pro是一个直观的应用程序,用于公寓和房屋的室内设计,以及几乎任何复杂的景观.专业版提供了一套扩展的工具和独特的出口质量. 下载 ► Live Home 3D Pro 下载安 ...
- Docker常用软件安装
jdk dockere pull openjdk:11 docker run -d -t --name java-11 openjdk:11 MySQL 可以从docker hup中查找自己想要安装的 ...
- 【小白晋级大师】如何设计一个支持10万人用的ChatGPT对接系统
不停地书写,方能不失在人海茫茫. 1.前言 之前给大家写了ChatGPT对接企业微信的教程,具体可看知乎链接: [奶奶看了都会]ChatGPT3.5接入企业微信,可连续对话 文章结尾说了教程只能适用于 ...
- AIArena Frontend 初步练习
尝试对starter项目的页面进行改变 修改侧边栏,只留下最上面的「仪表盘」和「列表页」两个大模块 in SideNav.vue the code for the sidebar menu is: & ...
- 在k8s安装CICD-devtron
在k8s安装CICD-devtron 先前条件 <kubernetes(k8s) 存储动态挂载>参考我之前的文档进行部署https://www.oiox.cn/index.php/arch ...
- Nordic芯片烧录指南
本文讲介绍Nordic系列芯片的烧录方式 一.准备工作 1.硬件 首先需要准备一块Nordic的DK或者Jlink,但是需要注意的是x宝购买的盗版Jlink因为没有license,用一段时间可能会被锁 ...
- JS引擎(2):Java平台上JavaScript引擎—Rhino/Nashorn概述
可以后端开发的 javascript引擎有 Chrome V8 基于C++ java的Rhino引擎(JDK6被植入),Java8 被替换为Nashorn Rhino和Nashorn都是用Java实现 ...