Algorithm 超出了算法时间限制

Algorithm 超出了算法时间限制,algorithm,data-structures,Algorithm,Data Structures,主题链接: 对于这个问题,我在测试41中超过了时间限制 我想使用的数据结构不合适,但我想了很长时间,不知道在哪里采用好的数据结构,请给我一些建议。 算法思想: 这种方法有点类似于选择排序。首先,找到一个幸运数字,然后用第一个数字交换位置,然后从第二个数字开始,找到最小的数字,然后用幸运数字交换位置,这样从第二个数字开始的最小数字被放在第一个位置,幸运数字现在在另一个位置,并且记录其位置。 然后将幸运数字与第二个数字交换,然后重复上述过程。需要特别注意的是,我们需要记录排序后所选幸运数字的位置,因

主题链接:

对于这个问题,我在测试41中超过了时间限制

我想使用的数据结构不合适,但我想了很长时间,不知道在哪里采用好的数据结构,请给我一些建议。

算法思想:

这种方法有点类似于选择排序。首先,找到一个幸运数字,然后用第一个数字交换位置,然后从第二个数字开始,找到最小的数字,然后用幸运数字交换位置,这样从第二个数字开始的最小数字被放在第一个位置,幸运数字现在在另一个位置,并且记录其位置。 然后将幸运数字与第二个数字交换,然后重复上述过程。需要特别注意的是,我们需要记录排序后所选幸运数字的位置,因为位置前后的过程略有不同,需要进行比较(这在代码注释中解释)


使用名称空间std;
typedef long-long-ll;
//判断它是否是一个幸运数字。如果是幸运数字,则返回true,否则返回false。
布尔法官(字符串x);
bool静态cmp(向量a,向量b){返回a[0]>n;
向量nums;
ll smLuckyNum=INT64_MAX;
对于(int i=0;i>x;
nums.推回(x);
如果(判断(to_string(x))&&smLuckyNum>x)smLuckyNum=x;//找到最小的幸运数字
}
向量b;//b[i][0]存储nums[i],b[i][1]存储i索引
int pos,origIndex;
布尔排序=真;
//b[i][0]存储nums[i]和b[i][1]存储i索引
对于(int i=0;inums[pos])MINID=pos;
if(MINIDnums[n-1])
ans.push_back(到_字符串(pos+1)+“”+到_字符串(n));

cout用于查找
MINID
的嵌套循环使运行时在n中为二次:

for(int j = i + 1; j < n; j++)
    if(nums[MINID] > nums[j]) MINID = j;
for(int j=i+1;jnums[j])MINID=j;
当n=100000时,这将花费很长时间。您需要找到更好的方法来计算
MINID


提示:您一开始就准备好了
b[]
,然后再也不用了。

是的,我本来想在这里使用优先级队列或set,但这样做会在您将幸运数字与位置I处的元素交换时更改b[I][1],因此您必须遍历树,在树中找到b[I][0]以更改其b[I][1],特别是在处理i>pos的情况下,你不能做简单的pop。逻辑太复杂了,我写不出来。你能不能用更聪明的方式指导我?这里有一个提示:
b[i][1]
已经告诉您哪个元素需要在位置i结束。假设到目前为止,我们已经将最小元素移到数组中的位置0,并且“枢轴”幸运元素位于位置100。要将第二小元素移到位置1和100,然后交换位置1和
b[1][1]
——但我们不能确定第二个最小的元素是否仍在位置
b[1][1]
,因为我们的掉期交易可能干扰了它。但是如果我们有第二个数组
c[i]
这告诉我们最初位于位置i的元素的当前位置?我可能知道你的意思。你的意思是我不需要编写for循环来找到最小的数字。我可以使用数组c来跟踪元素的移动,并使用数组b直接获得当前应放置的数字。这就是r怀特:)