2023-02-16:两种颜色的球,蓝色和红色,都按1~n编号,共计2n个, 为方便放在一个数组中,红球编号取负,篮球不变,并打乱顺序, 要求同一种颜色的球按编号升序排列,可以进行如下操作: 交换相邻
2023-02-16:两种颜色的球,蓝色和红色,都按1~n编号,共计2n个,
为方便放在一个数组中,红球编号取负,篮球不变,并打乱顺序,
要求同一种颜色的球按编号升序排列,可以进行如下操作:
交换相邻两个球,求最少操作次数。
[3,-3,1,-4,2,-2,-1,4]、
最终交换结果为:
[1,2,3,-1,-2,-3,-4,4]。
最少交换次数为10,
n <= 1000。
答案2023-02-16:
动态规划,IndexTree。
代码用rust编写。代码如下:
use std::collections::HashMap;
use std::iter::repeat;
fn main() {
let mut arr = vec![3, -3, 1, -4, 2, -2, -1, 4];
println!("{}", min_swaps(&mut arr));
}
// [3,-3,1,-4,2,-2,-1,4]
// -3 -4 -2 -1 -> -1 -2 -3 -4
// 3 1 2 4 -> 1 2 3 4
// 这个题写对数器太麻烦了
// 所以这就是正式解
fn min_swaps(arr: &mut Vec<i32>) -> i32 {
let n = arr.len() as i32;
let mut map: HashMap<i32, i32> = HashMap::new();
let mut top_a = 0;
let mut top_b = 0;
for i in 0..n {
if arr[i as usize] > 0 {
top_a = get_max(top_a, arr[i as usize]);
} else {
top_b = get_max(top_b, abs(arr[i as usize]));
}
map.insert(arr[i as usize], i);
}
let mut it = IndexTree::new(n);
for i in 0..n {
it.add(i, 1);
}
return f(top_a, top_b, &mut it, n - 1, &mut map);
}
// 可以改二维动态规划!
// 因为it的状态,只由topA和topB决定
// 所以it的状态不用作为可变参数!
fn f(top_a: i32, top_b: i32, it: &mut IndexTree, end: i32, map: &mut HashMap<i32, i32>) -> i32 {
if top_a == 0 && top_b == 0 {
return 0;
}
let mut p1 = i32::MAX;
let mut p2 = i32::MAX;
let mut index: i32;
let mut cost: i32;
let mut next: i32;
if top_a != 0 {
index = *map.get(&top_a).unwrap();
cost = it.sum(index, end) - 1;
it.add(index, -1);
next = f(top_a - 1, top_b, it, end, map);
it.add(index, 1);
p1 = cost + next;
}
if top_b != 0 {
index = *map.get(&(-top_b)).unwrap();
cost = it.sum(index, end) - 1;
it.add(index, -1);
next = f(top_a, top_b - 1, it, end, map);
it.add(index, 1);
p2 = cost + next;
}
return get_min(p1, p2);
}
fn get_max<T: Clone + Copy + std::cmp::PartialOrd>(a: T, b: T) -> T {
if a > b {
a
} else {
b
}
}
fn get_min<T: Clone + Copy + std::cmp::PartialOrd>(a: T, b: T) -> T {
if a < b {
a
} else {
b
}
}
fn abs(a: i32) -> i32 {
if a < 0 {
-a
} else {
a
}
}
struct IndexTree {
tree: Vec<i32>,
nn: i32,
}
impl IndexTree {
pub fn new(size: i32) -> Self {
Self {
tree: repeat(0).take((size + 1) as usize).collect(),
nn: size,
}
}
pub fn add(&mut self, mut i: i32, v: i32) {
i += 1;
while i <= self.nn {
self.tree[i as usize] += v;
i += i & -i;
}
}
pub fn sum(&mut self, l: i32, r: i32) -> i32 {
return if l == 0 {
self.sum0(r + 1)
} else {
self.sum0(r + 1) - self.sum0(l)
};
}
fn sum0(&mut self, mut index: i32) -> i32 {
let mut ans = 0;
while index > 0 {
ans += self.tree[index as usize];
index -= index & -index;
}
return ans;
}
}

2023-02-16:两种颜色的球,蓝色和红色,都按1~n编号,共计2n个, 为方便放在一个数组中,红球编号取负,篮球不变,并打乱顺序, 要求同一种颜色的球按编号升序排列,可以进行如下操作: 交换相邻的更多相关文章
- 【leetcode】Merge Sorted Array(合并两个有序数组到其中一个数组中)
题目: Given two sorted integer arrays A and B, merge B into A as one sorted array. Note: You may assum ...
- C语言:一个数组中只有两个数字是出现一次
//1.一个数组中只有两个数字是出现一次, //其他所有数字都出现了两次. //找出这两个数字,编程实现.a //^=单独两个数的^结果 //单独出现的两个数不同位的标记 //position: ^结 ...
- 选取两个有序数组中最大的K个值,降序存入另一个数组中
原题: 假设有两个有序的整型数组int *a1, int *a2,长度分别为m和n.试用C语言写出一个函数选取两个数组中最大的K个值(K可能大于m+n)写到int *a3中,保持a3降序,并返回a3实 ...
- C#把某个数组的一部分复制到另一个数组中的两种方法:Buffer.BlockCopy和Array.Copy
static void Main(string[] args) { , , , , , }; ;//目标数组大小 int int_size = sizeof(int);//用于获取值类型的字节大小. ...
- JS判断一个数组中是否有重复值的三种方法
方法一: var s = ary.join(",")+","; for(var i=0;i<ary.length;i++) { if(s.replace( ...
- js中关于一个数组中最大、最小值以及它们的下标的输出的一种解决办法
今天在学习js中的数组时,遇到的输出一个数组中最大.最小值以及它们的下表,以下是自己的解决方法! <script type="text/javascript"> var ...
- 一个数组中两个数的和为N,找出这两个数字的下标
分析,两个数字的和为N.那么这两个数字是否是唯一的呢?输出的下标是否是第一对出现的呢? 1,我们假设这两个数字是唯一的 和是唯一的,那么其中一个数字越大,另一个数字就越小.想到大小关系,我们就想到了排 ...
- 把两个table放在一个Repeater中显示
DataTable dt; DataTable dt1; HLoanApplyInfo applyInfo = HLoanApplyBll.GetModelById(FLoanID); FLoanID ...
- 数组中的数分为两组,让给出一个算法,使得两个组的和的差的绝对值最小,数组中的数的取值范围是0<x<100,元素个数也是大于0, 小于100 。
比如a[]={2,4,5,6,7},得出的两组数{2,4,6}和{5,7},abs(sum(a1)-sum(a2))=0: 比如{2,5,6,10},abs(sum(2,10)-sum(5,6))=1 ...
- 【LeetCode每天一题】Median of Two Sorted Arrays(两数组中的中位数)
There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the tw ...
随机推荐
- Visual Studio Tools for Apache Cordova 使用web技术构建使用Ios Andriod 和 windows 的应用
1.vs 开发web app 2.官方的解说
- MySQL 导出单表数据
1.导出指定表的数据 mysqldump -t database -u username -ppassword --tables table_name1 table_name2 table_name3 ...
- windows2012通过powershell安装远程组件技巧
概要: 通过服务器管理器安装远程桌面服务会报错一直没有办法解决 之后了解到安装组件可以通过powershell命令安装 powershell命令说明 https://docs.microsoft. ...
- linux虚拟机设置网络显示NetworkManager need to be running
问题描述:在设置一台centOS7虚拟机的网络时出现: 解决方法: 命令行重启NetworkManager systemctl restart NetworkManager 刷新一次就好了
- OSPF v3与v2的区别
- Unity图片转存及读取
[code]csharpcode: /// <summary> /// 加载图片 /// </summary> private Sprite LoadTexture(strin ...
- 使用Nginx实现本地目录映射
如果文件是存储在服务器的某个位置,想提供pdf.jpg.png.mp4这些文件的预览功能,可以使用Nginx做虚拟映射,防止他人知道该文件的绝对路径. 如果想预览office文件,先将office文件 ...
- JQ的尺寸类
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 方差分析1—单因素方差分析(R语言)
方差分析是由英国著名统计学家:R.A.Fisher推导,也叫F检验,用于多个样本间均数的比较(分析类别变量.有序变量).当包含的因子是解释变量时,关注的重点通常会从预测转向组别差异的分析.方差分析是一 ...
- Vulnhub Bravery靶机 Walkthrough
Bravery Recon 使用netdiscover对本地网络进行arp扫描. ┌──(kali㉿kali)-[~] └─$ sudo netdiscover -r 192.168.80.0/24 ...