Java 对排序数组的子数组leftshift方法的调用最少(访谈问题)

Java 对排序数组的子数组leftshift方法的调用最少(访谈问题),java,arrays,Java,Arrays,假设您有一个方法subrayleftshift(a,i),当n是数组长度时,该方法将子数组a[i,…,n-1]左移。这意味着元素a[i+1],…,a[n-1]向左移动一个位置,原始的a[i]将成为最后一个 更正式地说,这里是函数实现: public static void subArrayLeftShift(int[] a, int i){ if (a.length == 0) return; int last = a.length - 1; int insertToLast =

假设您有一个方法
subrayleftshift(a,i)
,当n是数组长度时,该方法将子数组a[i,…,n-1]左移。这意味着元素a[i+1],…,a[n-1]向左移动一个位置,原始的a[i]将成为最后一个

更正式地说,这里是函数实现:

public static void subArrayLeftShift(int[] a, int i){
  if (a.length == 0) return;

  int last = a.length - 1;
  int insertToLast = a[i];
  for (; i < last; i++){
      a[i] = a[i + 1];
  }
  a[last] = insertToLast;
}
publicstaticvoid子数组leftshift(int[]a,int i){
如果(a.length==0)返回;
int last=a.长度-1;
int insertToLast=a[i];
对于(;i
现在来看问题:实现一个函数,该函数接收未排序的数组,并返回对
子数组leftshift
进行排序的最小调用次数

在面试中我找不到做这件事的方法。我成功地为我为直觉写的每个例子找到了最少的调用次数,但找不到一种方法来概括它

你知道怎么解决吗?

公共静态int-minimumCalls(int[]a){
public static int minimumCalls(int[] a) {

    int minCalls = 0;

    for (int i = 0; i < a.length - 1; i++) {
        for (int j = i+1; j < a.length; j++) {
            if (a[i] > a[j]) {
                minCalls++;
                break;
            }
        }
    }

    return minCalls;
}
int=0; 对于(int i=0;ia[j]){ minCalls++; 打破 } } } 回电话; }
我的想法是,只要子数组中存在小于当前
i
的任何值,就必须调用该方法一次。我觉得,这种方法的名称是subrayshiftleft
,它的设计目的是让你摆脱这种想法,把你的注意力从简单的想法中拖开

如果数组中有任何小于当前值的值,只需调用该方法即可


将其视为将一个较大的值移动到数组末尾比将较小的值向左移动要容易得多。我建议使用以下算法来解决此问题:

  • 查找数组中未排序的最小数字(数组右侧的数字较小)。让这个数字为x
  • 计算数组中有多少个数字大于先前找到的数字x。让这个数字是y

由于每次调用函数时,未排序的数字都会在最后一个位置结束,因此最佳策略是按递增顺序调用每个未排序数字的函数。使用之前发现的,我们从x开始。我们继续使用下一个大于x的未排序数字,因为这样,它将在x的右边结束,因此它将被排序。以同样的方式继续。多少钱?我们有多少比x大的数字?好吧,那是y。因此,总的来说,调用函数的次数是1+y

发布你的直觉代码并不是一件丢脸的事。它看起来像是插入排序。所以,我相信最大呼叫数是
N
,但最小呼叫数取决于数据,甚至可能是
0
,请不要破坏您的帖子。通过在Stack Exchange网络上发布,您已授予SE分发该内容的不可撤销的权利(根据)。根据SE政策,任何破坏行为都将被恢复。你说得对。我在发布后不久就发现了这一点。正在研究如何回避这个问题。