讲师在课堂上提出这个问题: [问题]
存储n个整数的序列 数组A [1..n]。 A中的整数a是 如果它看起来更多,则称为多数 超过A / n的2次。
可以设计O(n)算法 找到大多数基于 以下观察:如果两个 原始的不同元素 序列被删除,然后 在原始序列中占多数 仍然是新的大多数 序列。使用这个观察,或 否则,编写编程代码 找到大多数,如果存在,进入 O(n)时间。
接受此解决方案 [溶液]
int findCandidate(int[] a)
{
int maj_index = 0;
int count = 1;
for (int i=1;i<a.length;i++)
{
if (a[maj_index] == a[i])
count++;
else
count--;
if (count == 0)
{
maj_index =i;
count++;
}
}
return a[maj_index];
}
int findMajority(int[] a)
{
int c = findCandidate(a);
int count = 0;
for (int i=0;i<a.length;i++)
if (a[i] == c) count++;
if (count > n/2) return c;
return -1;//just a marker - no majority found
}
我看不出解决方案是如何提供动态解决方案的。而且我看不出如何根据措辞,他把那个代码拉出来。
答案 0 :(得分:3)
origin of the term dynamic programming试图描述一种非常棒的优化某种解决方案的方法(动态被使用,因为它听起来更有力)。换句话说,当您看到“动态编程”时,您需要将其转换为“非常棒的优化”。
答案 1 :(得分:2)
'Dynamic programming'与动态分配内存无关,它只是一个古老的术语。事实上,它与“编程”的现代化也没什么关系。
这是一种解决特定类问题的方法 - 当子问题的最优解被保证成为更大问题的最优解的一部分时。例如,如果您想以最少的账单支付567美元,该解决方案将包含至少一个解决方案,价格为1美元,566美元,还有一个账单。
代码只是算法的一个应用程序。
答案 2 :(得分:0)
这是动态编程,因为findCandidate函数将提供的数组分解为更小,更易于管理的部分。在这种情况下,他从第一个阵列开始作为大多数人的候选人。通过在遇到计数时增加计数并在不存在时减少计数,他确定这是否为真。当计数等于零时,我们知道前i个字符没有多数。通过不断计算局部多数,我们不需要在候选识别阶段多次迭代数组。然后我们通过第二次遍历数组来检查该候选者是否实际上是多数,给我们O(n)。它实际上在2n时间内运行,因为我们迭代两次,但常量并不重要。