首页 > 其他分享 >2023-09-16:用go语言,给你一个整数 n 和一个在范围 [0, n - 1] 以内的整数 p , 它们表示一个长度为 n 且下标从 0 开始的数组 arr , 数组中除了下标为 p 处是 1

2023-09-16:用go语言,给你一个整数 n 和一个在范围 [0, n - 1] 以内的整数 p , 它们表示一个长度为 n 且下标从 0 开始的数组 arr , 数组中除了下标为 p 处是 1

时间:2023-09-27 12:33:15浏览次数:48  
标签:下标 cur int banned 整数 数组 ans return


2023-09-16:用go语言,给你一个整数 n 和一个在范围 [0, n - 1] 以内的整数 p ,

它们表示一个长度为 n 且下标从 0 开始的数组 arr ,

数组中除了下标为 p 处是 1 以外,其他所有数都是 0 。

同时给你一个整数数组 banned ,它包含数组中的一些位置。

banned 中第 i 个位置表示 arr[banned[i]] = 0 ,题目保证 banned[i] != p 。

你可以对 arr 进行 若干次 操作。一次操作中,你选择大小为 k 的一个 子数组

并将它 翻转 。在任何一次翻转操作后,

你都需要确保 arr 中唯一的 1 不会到达任何 banned 中的位置。

换句话说,arr[banned[i]] 始终 保持 0 。

请你返回一个数组 ans ,对于 [0, n - 1] 之间的任意下标 i ,

ans[i] 是将 1 放到位置 i 处的 最少 翻转操作次数,

如果无法放到位置 i 处,此数为 -1 。

子数组 指的是一个数组里一段连续 非空 的元素序列。

对于所有的 i ,ans[i] 相互之间独立计算。

将一个数组中的元素 翻转 指的是将数组中的值变成 相反顺序 。

输入:n = 4, p = 0, banned = [1,2], k = 4。

输出:[0,-1,-1,1]。

来自左程云

答案2023-09-16:

步骤如下:

1.创建一个奇数集合(oddSet)和一个偶数集合(evenSet)。

2.将所有奇数(除了p和banned中的位置)添加到oddSet中。

3.将所有偶数(除了p和banned中的位置)添加到evenSet中。

4.创建一个长度为n的数组ans,初始化全部为-1。

5.创建一个队列queue和两个指针l和r,初始化r=0。

6.将p放入队列queue中,r加1。

7.初始化level=0。

8.当l < r时,执行以下步骤:

  • 取出队列头部元素cur。
  • 将level赋值给ans[cur]。
  • 计算cur左边和右边的范围,分别为left和right。
  • 根据left的奇偶性,选择对应的集合curSet(如果left是偶数,则curSet为evenSet;否则为oddSet)。
  • 在curSet中查找大于等于left的最小元素,并将其加入队列queue中,r加1。
  • 从curSet中移除该元素。
  • 重复以上步骤,直到curSet中没有大于等于left的元素。
  • l加1。

9.更新level,重复步骤8直到l < r不成立。

10.返回ans。

时间复杂度:假设n为数组长度,遍历数组需要O(n)的时间复杂度,每次操作需要在集合中查找和移除元素,集合的查找和移除操作的时间复杂度为O(log n)。总体时间复杂度为O(n log n)。

空间复杂度:创建两个集合,集合的空间复杂度为O(n),创建一个队列,队列的空间复杂度为O(n),创建一个数组,数组的空间复杂度为O(n),总体空间复杂度为O(n)。

go完整代码如下:

package main

import (
	"fmt"

	"github.com/emirpasic/gods/sets/treeset"
)

func minReverseOperations(n int, p int, banned []int, k int) []int {
	oddSet := treeset.NewWithIntComparator()
	evenSet := treeset.NewWithIntComparator()

	for i := 1; i < n; i += 2 {
		oddSet.Add(i)
	}
	for i := 0; i < n; i += 2 {
		evenSet.Add(i)
	}

	for _, ban := range banned {
		oddSet.Remove(ban)
		evenSet.Remove(ban)
	}

	oddSet.Remove(p)
	evenSet.Remove(p)

	ans := make([]int, n)
	for i := range ans {
		ans[i] = -1
	}

	queue := make([]int, n)
	l := 0
	r := 0
	queue[r] = p
	r++

	level := 0
	for l < r {
		end := r
		for l < end {
			cur := queue[l]
			ans[cur] = level

			left := max(cur-k+1, k-cur-1)
			right := min(cur+k-1, n*2-k-cur-1)

			curSet := oddSet
			if (left & 1) == 0 {
				curSet = evenSet
			}

			_, ceiling := curSet.Find(func(index int, value interface{}) bool {
				if value.(int) >= left {
					return true
				} else {
					return false
				}
			})

			for ceiling != nil && ceiling.(int) <= right {
				queue[r] = ceiling.(int)
				r++
				curSet.Remove(ceiling)
				_, ceiling = curSet.Find(func(index int, value interface{}) bool {
					if value.(int) >= left {
						return true
					} else {
						return false
					}
				})
			}

			l++
		}
		level++
	}

	return ans
}

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

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

func main() {
	n := 4
	p := 0
	banned := []int{1, 2}
	k := 4

	result := minReverseOperations(n, p, banned, k)
	fmt.Println(result)
}

2023-09-16:用go语言,给你一个整数 n 和一个在范围 [0, n - 1] 以内的整数 p , 它们表示一个长度为 n 且下标从 0 开始的数组 arr , 数组中除了下标为 p 处是 1_空间复杂度


标签:下标,cur,int,banned,整数,数组,ans,return
From: https://blog.51cto.com/moonfdd/7623129

相关文章

  • 测试驱动技术(TDD)系列之3:详解Java数组
    在前面的文章中我介绍了如何通过junit4和TestNG实现参数化,这两种架构都通过二维数组来实现参数化,在这里我就给大家详细的介绍一下java数组。Junit4定义参数化数据,代码如下:publicstaticCollectionprepareData(){Object[][]object={{1,2,3},{0,2,2},{0,3,3}};returnArrays.as......
  • python range中的步长必须是整数 numpy则可以是小数
    >>>foriiinrange(1,10,0.1): print(ii)Traceback(mostrecentcalllast):File"<pyshell#4>",line1,in<module>foriiinrange(1,10,0.1):TypeError:'float'objectcannotbeinterpretedasaninteger>>......
  • 子数组之和
    子数组之和题目地址https://www.lintcode.com/problem/subarray-sum/my-submissions描述给定一个整数数组,找到和为零的子数组。你的代码应该返回满足要求的子数组的起始位置和结束位置样例样例1:输入:[-3,1,2,-3,4]输出:[0,2]或[1,3] 样例解释:返回任意一段和为......
  • 剑指offer(1)数组中重复的数字
    描述在一个长度为n的数组里的所有数字都在0到n-1的范围内。数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。例如,如果输入长度为7的数组[2,3,1,0,2,5,3],那么对应的输出是2或者3。存在不合法的输入的话输出-1数据......
  • C语言双指针法解决-有序数组的平方
     力扣(LeetCode)官网-全球极客挚爱的技术成长平台/***Note:Thereturnedarraymustbemalloced,assumecallercallsfree().*/intcmp(constvoid*a,constvoid*b){return(*(int*)a)-(*(int*)b);}int*sortedSquares(int*nums,intnumsSize,......
  • 取模算术运算符-应用3-分解一个整数
    C语言中分解一个整数需要使用到整除和取余运算符。两个整数相除只会保留整数,一个数对另外一个数取余,会得到余数。示例代码如下: #include<stdio.h>voidmain(){ intnum=521; intbai,shi,ge; //整除100,只会保留整数部分的百位 bai=num/100; ......
  • 【踩坑】JS/TS 整数明明没有超过 Number.MAX_VALUE,为啥精度还是丢失了?
    代码functioncalcKey(props){returnprops.reduce((key,prop,index)=>{constcode=prop[0]*(15+1)+prop[1];console.log(code);console.log(key);returnkey+code*Math.pow(1000,index);},0);}func......
  • 【面试题】Js数组去重都有哪些方法?
    1.indexOf定义:indexOf()方法可返回某个指定的字符串值在字符串中首次出现的位置。如果没有找到匹配的字符串则返回-1。注意:iindexOf()方法区分大小写。语法:string.indexOf(searchvalue,start)//;searchvalue必需。searchvalue可选参数。返回值:Number//查找指定字符串第一次......
  • JavaScript 终于原生支持数组分组了!
    在日常开发中,很多时候需要对数组进行分组,每次都要手写一个分组函数,或者使用lodash的groupBy函数。好消息是,JavaScript现在正在引入全新的分组方法:Object.groupBy和Map.groupBy,以后再也不需要手写分组函数了,目前最新版本的Chrome(117)已经支持了这两个方法!以前的数组分组假设有一个......
  • 关于keil导出数组、数据全是0解决方法
    最近我在采集spwm的电压,想导出散点用matlab画一下图,就找一些keil导出数据的方法,我到用这种写函数的的方式,结果导出全是0,找了很多帖子都没有解释。后来仔细看看才发现是一个十分低级的错误,在别的帖子上转载的都是printf("%d\n",a[i]);打印的都是整形,而我的数组是float类型,所以......