【发布时间】:2012-08-29 16:53:06
【问题描述】:
我最近接受了一次采访,被问到这个问题。让我正确解释这个问题:
给定一个数字 M(N 位整数)和 K 次交换操作(一个交换 操作可以交换 2 位),设计一个算法来获得最大值 可能的整数?
示例:
M = 132 K = 1 输出 = 312
M = 132 K = 2 输出 = 321
M = 7899 k = 2 输出 = 9987
我的解决方案(伪代码算法)。我使用最大堆在每个 K 操作中从 N 位中获取最大位,然后适当地交换它。
for(int i = 0; i<K; i++)
{
int max_digit_currently = GetMaxFromHeap();
// The above function GetMaxFromHeap() pops out the maximum currently and deletes it from heap
int index_to_swap_with = GetRightMostOccurenceOfTheDigitObtainedAbove();
// This returns me the index of the digit obtained in the previous function
// .e.g If I have 436659 and K=2 given,
// then after K=1 I'll have 936654 and after K=2, I should have 966354 and not 963654.
// Now, the swap part comes. Here the gotcha is, say with the same above example, I have K=3.
// If I do GetMaxFromHeap() I'll get 6 when K=3, but I should not swap it,
// rather I should continue for next iteration and
// get GetMaxFromHeap() to give me 5 and then get 966534 from 966354.
if (Value_at_index_to_swap == max_digit_currently)
continue;
else
DoSwap();
}
时间复杂度:O(K*( N + log_2(N) ))
// K-times [log_2(N) for pop out number from heap & N to get most right index to swap with]
上面的策略在这个例子中失败了:
M = 8799 和 K = 2
按照我的策略,我将在 K=1 后得到 M = 9798,在 K=2 后得到 M = 9978。但是,在 K=2 之后,我能得到的最大值是 M = 9987。
我错过了什么?
还建议解决问题的其他方法和优化我的解决方案的方法。
【问题讨论】:
-
难道您不能对数字进行桶排序,绘制出最佳位置,然后遍历每个数字,将其切换到最佳位置吗?我很确定它是 N 位数的订单。
-
K是您被允许执行的交换操作的数量吗,每个交换交换两位数?如果是这样,那么您有“K交换操作”,而不是“K-swap 操作”。 -
@SteveJessop:谢谢。我已经更新了问题。
-
@Jatin:在失败的情况下你错过的是,如果你有 8799 和 2 个可用交换,你应该执行的第一次交换与你应该执行的第一次交换不同如果您有 8799 但只有 1 个交换可用。您的方法是“贪婪”的,这意味着它会优化每一步的结果,但贪婪算法在这里不起作用。
-
@Jatin,关于复杂性的小问题:O(K*( N + log_2(N) )) 是 O(K*N)
标签: algorithm