Nit*_*esh 0 arrays algorithm math perl
我有一个阵列
[3, 1, 2, 5, 4, 6]
Run Code Online (Sandbox Code Playgroud)
我想将其排序(更改sort为arranging in a certain pattern)为:向右移动并将索引替换为右侧的下一个最高整数.说在这个数组中3被替换为5,1被替换为2等等.
我希望输出为
[5, 2, 5, 6, 6, 6]
Run Code Online (Sandbox Code Playgroud)
算法:
这是一种常规算法.但时间复杂度是n*n.(不完全是n*n).
有没有办法降低复杂性.因为在大型阵列的情况下,它会非常慢.有人可以为我提供时间复杂度的算法n.
添加代码
use strict;
use warnings;
my @arr1 = qw/3 1 2 5 4 6/;
my @arr2;
my ($j, $i);
for($i = 0; $i <= $#arr1; $i++) {
$j = $i;
while ( $j < $#arr1) {
if ( $arr1[$i] < $arr1[$j+1]) {
push @arr2,$arr1[$j+1];
last;
}
if ($i == $#arr1) {
push @arr2,$arr1[$j];
}
$j++;
}
}
push @arr2, $arr1[$#arr1]; ## Pushing the last array index
print @arr2;
Run Code Online (Sandbox Code Playgroud)
输出:
525666
您当前的算法可以多次触摸一个位置,这是低效的.通过递归的力量,我们可以做得更好.想象一个执行排序的函数,直到找到比某些更高的数字$n:
[3, 1, 2, 5, 4, 6] # start here
#^
[3, 1, 2, 5, 4, 6] # look at next number. It's smaller, so we recurse
#^--^
[3, 1, 2, 5, 4, 6] # in recursion: look at next number, replace
#^ ^--^
#|__|
[3, 2, 2, 5, 4, 6] # return new index. It's smaller, so we recurse
#^ ^
#|_____|
[3, 2, 2, 5, 4, 6] # in recursion: look at next number, replace
#^ ^--^
#|_____|
[3, 2, 5, 5, 4, 6] # return new index
#^ ^
#|________|
[3, 2, 5, 5, 4, 6] # It's larger, so we replace and go to new index
#^--------^
[5, 2, 5, 5, 4, 6] # Look at next number. It's smaller, so we recurse
# ^--^
[5, 2, 5, 5, 4, 6] # In recursion: replace
# ^ ^--^
# |__|
[5, 2, 5, 5, 6, 6] # return new index
# ^ ^
# |_____|
[5, 2, 5, 5, 6, 6] # It's larger, so we replace. Go to new index
# ^-----^
[5, 2, 5, 6, 6, 6] # Done!
Run Code Online (Sandbox Code Playgroud)
困难的部分是编写一个执行此操作的函数.由于我们想要编写递归函数,我们必须反思:
[] - 空数组(没有索引)对自身进行排序[6] - 具有单个元素的数组对该元素进行排序[4, 6] ? [6, 6] - 如果下一个索引处的元素较大,则将其复制并将新索引放在下一个元素处[5, 4, ...] - 如果下一个元素较小,则递归该索引.示例实现:
sub weird_sort {
my ($array, $start, $return) = @_;
$start //= 0;
my $next = $start + 1;
while ($next <= $#$array) {
# check if one is larger
if ($array->[$start] < $array->[$next]) {
$array->[$start] = $array->[$next];
return $next if $return; # return index to higher levels so that they
# can check whether the $next elem is larger.
$start = $next;
$next = $start + 1;
}
else {
$next = weird_sort($array, $next, 1);
}
}
return $next;
}
# called in-place like
weird_sort(\@array);
Run Code Online (Sandbox Code Playgroud)
下一步是删除递归:
sub weird_sort {
my ($array) = @_;
my ($start, $next) = (0, 1);
my @stack;
while ($next <= $#$array) {
# check if one is larger
if ($array->[$start] < $array->[$next]) {
$array->[$start] = $array->[$next];
($start, $next) = @stack ? (pop(@stack), $next) : ($next, $next + 1);
}
else {
push @stack, $start;
($start, $next) = ($next, $next + 1);
}
}
}
Run Code Online (Sandbox Code Playgroud)
这似乎适用于简单的情况,但我不完全确定这是一个通用的解决方案.