通过从给定数字中删除n位来构建最小数字

时间:2016-06-28 08:56:12

标签: arrays algorithm perl

它将输入数字(字符串)作为输入,然后任务是删除n个数字以得到最终可能的最小数字,但是您必须处理顺序,即约束。您无法更改原始数字的顺序。

我希望它能在O(n)中工作,所以我这样做了:

#!/usr/bin/perl
#lowestNS.pl
#Date: 2016-06-28

use warnings;
use strict;
use utf8;

(@ARGV == 2) or die "2 args needed";
my $num = $ARGV[0];
my $d = $ARGV[1];
my @arr;

int($num) > 0 or die "Enter positive number";

print "Number in: $num\nDel: $d\n";

if(int($num) == 0) {
    print "Result: 0\n";
    exit;
}
else {
    my $str = $num;
    @arr = split(//, $str); #/Split on each number
    #Split and multiply by reverse index, to give precedence to the order of numbers
    for(my $i = 0; $i < @arr; $i++) {
        $arr[$i] *= (@arr - $i);
    }
}

print "arr: " . join(',' , @arr) . "\n";

for (my $j = 0; $j < $d; $j++) {
    my $max = $arr[0];
    my $m_index = -1;

    #replace nth maximum with -1

    for (my $i = 0; $i < @arr; $i++) {
        if($max <= $arr[$i]) {
            $max = $arr[$i];
            $m_index = $i;
        }
    }
    $arr[$m_index] = -1;
}


#return all numbers with value other than -1

my $result = "";

for (my $i = 0; $i < @arr; $i++) {
    if($arr[$i] != -1){
        $result = $result . "" . $arr[$i]/(@arr - $i);
    }
}

print "Result: $result\n";

除了以下情况外,它适用于所有情况:
Number = 765028321 Delete = 5
问题是删除7650 2 8321时应删除765028 3 21。 因为2 * 5&gt; 3 * 3。

2 个答案:

答案 0 :(得分:1)

我认为,该算法很简单:

假设,N是要删除的位数;
1.找到前N位数中的第一个最小数字,删除其左侧的数字,将N减去删除的位数。
2.如果N> 0,则将数字向右移动并重复上述步骤 当然,我们需要检查边际情况,并确保最终数字不以0开头 这是代码草案:

#!/usr/bin/perl
use strict;
use warnings;
my ($number, $del)=@ARGV;
my @num = $number=~m{.}g;
my $curpos=0;
my @finalnum;
for(;;) {
  last if $del <=0 || $curpos+$del>=@num;
  my $minpos=$curpos;
  for (my $i=$curpos;$i<$curpos+$del+1 && $i < @num;$i++) {
    if ($num[$i]<$num[$minpos] && !($curpos==0 && $num[$i]==0)) {
      $minpos=$i;
    }
  }
  push @finalnum, $num[$minpos];
  $del-=($minpos-$curpos);
  $curpos=$minpos+1;
}
push @finalnum, @num[$curpos+$del..$#num] if $curpos+$del < @num;
print join '', @finalnum;

答案 1 :(得分:-1)

可能的解决方案是:

  1. 创建一个具有所有数字计数的数组,例如。在您的情况下,此数组将如下所示:1,1,2,1,0,1,1,1,1,0

  2. 然后,以贪婪的方式删除所有big个数字,尽可能多。因此,您删除9s,但由于其计数为0,您仍需要删除5位数。删除8s,所以你仍然需要删除4位数字,依此类推。

  3. 这种情况有点微不足道,所以你将留下2 2's, 1 1's and 1 0's。在那里,比如数字3 4's,你需要删除1 4.所以,你将删除所需的最左边的部分删除。

  4. 它是一种贪婪的方法,适用于O(n)。