C# 查找数组中给定范围内的最小数
嗨,我有一个大小为N的数组。数组值总是只有1、2、3个整数值。现在我需要找到给定数组索引范围内的最小值。例如,数组=2123132。[2-4]=1、[4-5]=2、[7-8]=3等范围的最低值 下面是我的代码:C# 查找数组中给定范围内的最小数,c#,loops,c#-4.0,optimization,comparison,C#,Loops,C# 4.0,Optimization,Comparison,嗨,我有一个大小为N的数组。数组值总是只有1、2、3个整数值。现在我需要找到给定数组索引范围内的最小值。例如,数组=2123132。[2-4]=1、[4-5]=2、[7-8]=3等范围的最低值 下面是我的代码: static void Main(String[] args) { string[] width_temp = Console.ReadLine().Split(' '); int[] width = Array.ConvertAll(width_temp,Int32.P
static void Main(String[] args) {
string[] width_temp = Console.ReadLine().Split(' ');
int[] width = Array.ConvertAll(width_temp,Int32.Parse); // Main Array
string[] tokens_i = Console.ReadLine().Split(' ');
int i = Convert.ToInt32(tokens_i[0]);
int j = Convert.ToInt32(tokens_i[1]);
int vehicle = width[i];
for (int beg = i+1; beg <= j; beg++) {
if (vehicle > width[beg]) {
vehicle = width[beg];
}
}
Console.WriteLine("{0}", vehicle);
}
static void Main(字符串[]args){
string[]width_temp=Console.ReadLine().Split(“”);
int[]width=Array.ConvertAll(width_temp,Int32.Parse);//主数组
string[]tokens_i=Console.ReadLine().Split(“”);
int i=转换为32(标记_i[0]);
int j=转换为32(令牌_i[1]);
int车辆=宽度[i];
对于(整数beg=i+1;beg宽度[beg]){
车辆=宽度[beg];
}
}
控制台写入线(“{0}”,车辆);
}
上面的代码运行良好。但我关心的是效率。在上面我只取了一组数组范围,但实际上会有n个范围,我必须返回每个范围的最小值。现在的问题是,如果有一个像[0-N]这样的范围,N是数组大小,那么我最终会比较所有项的最小值。因此,我想知道是否有一种方法可以优化代码以提高效率???我认为这是一种RMQ(范围最小查询),有几种实现可能适合您的场景
这是一个很好的封面,有很多,我推荐其中两个:
使用本教程中的符号,将
定义为
,有两个著名的、通用的实现/数据结构可以处理RMQ:平方根数组&
分段树是一种著名的但很难实现的方法,它可以解决
中的RMQ问题,它比平方根数组(
)具有更好的复杂性
平方根数组(
)
请注意,它不是该技术的正式名称,也不是任何数据结构,事实上,我不知道自从我学会它以来,是否有任何该技术的正式名称……但我们开始吧
对于查询时间,这肯定不是解决RMQ的最佳方法,但它有一个优点:易于实现!(与段树相比…)
以下是其工作原理的高级概念:
假设N是数组的长度,我们将数组分成sqrt(N)组,每个组包含sqrt(N)元素
现在我们使用O(N)
time来找到每个组的最小值,将它们存储到另一个数组调用M
因此,使用上述数组,M[0]=min(A[0..2]),M[1]=min(A[3..5]),M[2]=min(A[6..8]),M[3]=min(A[9..9])
(TopCoder教程中的图像存储最小元素的索引)
现在让我们看看如何查询: 对于任何范围
[p..q]
,我们最多可以将该范围分成3个部分
左边界的两部分,即不能形成一个完整组的一些剩余元素
一部分是中间的元素,它们形成了一些组
使用相同的示例,RMQ(2,7)
可以分为3部分:
A[2]
A[6],A[7]
A[3]、A[4]、A[5]
M
预处理了它们的最小值,因此我们不需要查看每个元素,我们可以查看和比较M
,相反,它们中最多有O(sqrt(N))
(毕竟是M
的长度)
对于边界部分,由于它们不能根据定义形成一个完整的组,这意味着它们最多有O(sqrt(N))
(这毕竟是一个完整组的长度)
因此,组合两个边界部分,元素之间有一部分,我们只需要比较O(3*sqrt(N))=O(sqrt(N))
元素
您可以参考教程了解更多详细信息(甚至是一些伪代码)。我认为这是一个RMQ(范围最小查询),有几种实现可能适合您的场景
这是一个很好的封面,有很多,我推荐其中两个:
使用本教程中的符号,将
定义为
,有两个著名的、通用的实现/数据结构可以处理RMQ:平方根数组&
分段树是一种著名的但很难实现的方法,它可以解决
中的RMQ问题,它比平方根数组(
)具有更好的复杂性
平方根数组(
)
请注意,它不是该技术的正式名称,也不是任何数据结构,事实上,我不知道自从我学会它以来,是否有任何该技术的正式名称……但我们开始吧
对于查询时间,这肯定不是解决RMQ的最佳方法,但它有一个优点:易于实现!(与段树相比…)
以下是其工作原理的高级概念:
假设N是数组的长度,我们将数组分成sqrt(N)组,每个组包含sqrt(N)元素
现在我们使用O(N)
time来找到每个组的最小值,将它们存储到另一个数组调用M
因此,使用上述数组,M[0]=min(A[0..2]),M[1]=min(A[3..5]),M[2]=min(A[6..8]),M[3]=min(A[9..9])
(TopCoder教程中的图像存储最小元素的索引)
现在让我们看看如何查询: 对于任何范围
[p..q]
,我们最多可以将该范围分成3个部分
左边界的两个部分,即不能形成一个完整组的一些剩余元素
List<int> numbers = new List<int> {2, 1, 3, 1, 2, 3, 1, 3, 3, 2};
int minindex =1, maxindex =3, minimum=-1;
if(minindex <= maxindex && maxindex>=0 && maxindex >=0 && maxindex < numbers.Count())
{
minimum = Enumerable.Range(minindex, maxindex-minindex+1) // max inclusive, remove +1 if you want to exclude
.Select(x=> numbers[x]) // Get the elements between given indices
.Min(); // Get the minimum among.
}
int[] inputArray = { 2, 1, 3, 1, 2, 3, 1, 3, 3, 2 };
int minIndex = 2;
int maxIndex = 5;
int minVal = 3;
for (int i = minIndex; i <= maxIndex; i++)
{
if (inputArray[i] <= minVal)
minVal = inputArray[i];
}
Console.WriteLine("Minimum value in the Given range is ={0}", minVal);
int[] intialArray = new int[] { 3, 3, 3, 3, 2, 2, 2, 1 };
int[] searchArray = new int[] { 4, 4, 4, 4, 7, 7, 7, 7 };