把一个数组向右循环移动k位要求时间复杂度为O(n)

今晚做了下某公司的网络笔试题,好久没刷题了,现在渣得要死,里面有道程序设计题是 把一个数组向右循环移动k位要求时间复杂度为O(n) 给的方法定义为

public void solution(int a[],int length,int k)

我当时觉得挺容易的,结果一写出来发现只能移一位。。。

public void solution(int []a,int length,int k){

    int temp=a[length-1];
    for(int j=length-1;j>0;j--){
        a[j]=a[j-1];
    }
    a[0]=temp;
}

然后发现再加个循环不就可以移动k位了吗?。。可是时间复杂度为O(k*n)了。。最后O(n)的算法有问题没时间了就用了这个。。

public void solution(int []a,int length,int k){
    for(int i=0;i<k;i++){
            int temp=a[length-1];//这里最后还写错了没减一。。
        for(int j=length-1;j>0;j--){
            a[j]=a[j-1];
        }
            a[0]=temp;
    }
}   

刚才突然想起,其实可以直接把第一个数往右移k位,第二位跟在第一个数后面,第三个跟着第二个后面不就可以了吗。。。

#include<iostream.h>
void convert(int a[], int start, int end)
{
    int k, temp;
    for (k = 0; k < (end-start+1)/2; k++)
    {
        temp = a[start+k];
        a[start+k] = a[end-k];
        a[end-k] = temp;
    }
}

void yiwei(int a[], int n, int k)
{
    convert(a,0,k-1);//先将数组前k个数逆置(0~k-1),
    convert(a,k,n-1);//先将数组后n-k个数逆置(k~n-1),
    convert(a,0,n-1);//先将整个数组逆置,
}

void main()
{
    int a[6] = {1,2,3,4,5,6};
    yiwei(a,6,2);
    for (int i = 0; i < 6; i++)
        cout << a[i] << ‘\t‘;
}
时间: 2024-10-11 21:43:31

把一个数组向右循环移动k位要求时间复杂度为O(n)的相关文章

算法题:找出一个数组中依次最大的k个元素

package arithmetic; import java.util.Arrays; /** * 找出一个数组中依次最大的k个元素 * @author SHI */ public class FindMaxFigure { public static void main(String[] args) { int[] a=new int[]{1,5,-1,8,0,2}; System.out.println(Arrays.toString(findBigFigure(a, 3))); } /*

实现将一维数组A(下标从1开始)中的元素循环右移k位,要求只用一个元素大小的辅助空间

#include<stdio.h>main(){ int n,arrary[50],k,temp; printf("请输入数组元素个数:\n"); scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&arrary[i]); printf("请输入数组需要向后移动的大小:\n"); scanf("%d",&k);if(k

输入一个数组,求最小的K个数

被这道题困了好久,看了剑指Offer才知道OJ上的要求有点迷惑性. 题目: 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4. 一直以为要按照顺序输出,想的方法是插入排序算法复杂度是O(N*K),当然这个地方就显得自己有点蠢了.不过我想在“按序输出”的错误题意下还没有啥更好的方法. 然后看了剑指Offer原书,原来输出不必按照顺序.所以第一种方法是快速选择.这种方法算法复杂度是O(N).不过在实际的使用中可能有点隐含的时间参数

经典算法——数组的循环右移K位

void Reverse(vector<int>&nums,int p,int q) { for(;p<q;p++,q--) { int temp=nums[q]; nums[q]=nums[p]; nums[p]=temp; } } void RightShift(vector<int> nums,int k) { int n=nums.size(); k%=n; Reverse(nums,0,n-k-1); Reverse(nums,n-k,n-1); Rever

【算法编程】循环右移一个数组

仅用一个辅助节点将一个大小为n数组循环右移k位的三种办法: 1.时间复杂度最大:将所有元素每次只移动一位,总共移动k次,程序实现十分容易,在此就不具体实现了. 2.时间复杂度适中:依次将每个元素都放到辅助节点上,然后将其储存到目的节点,具体程序如下: #include<iostream> using namespace std; int gcd(int x,int y); int main() { int n,k; cout<<"请输入数组的维数"<<

有序数组寻找中位数以及寻找K大元素

问题描述: 两个排序的数组A和B分别含有m和n个数,找到两个排序数组的中位数,要求时间复杂度应为O(log (m+n)).转化成找到两个数组的第K大数字进行解决 解题方法: 对于一个长度为n的已排序数列a,若n为奇数,中位数为a[n / 2 + 1] , 若n为偶数,则中位数(a[n / 2] + a[n / 2 + 1]) / 2如果我们可以在两个数列中求出第K小的元素,便可以解决该问题不妨设数列A元素个数为n,数列B元素个数为m,各自升序排序,求第k小元素取A[k / 2] B[k / 2]

删除一个数的K位使原数变得最小

原创 给定一个n位正整数a, 去掉其中k个数字后按原左右次序将组成一个新的正整数.对给定的a, k寻找一种方案,使得剩下的数字组成的新数最小. 提示:应用贪心算法设计求解 操作对象为n位正整数,有可能超过整数的范围,存储在数组a中,数组中每一个数组元素对应整数的一位数字. 在整数的位数固定的前提下,让高位的数字尽量小,整数的值就小.这就是所要选取的贪心策略. 每次删除一个数字,选择一个使剩下的数最小的数字作为删除对象. 当k=1时,对于n位数构成的数删除哪一位,使得剩下的数据最小.删除满足如下条

将数组元素循环右移k个位置(Java实现)

用四种方法实现了将数组元素循环右移k个位置,相关的解释作为注释放在代码里面了. package movearrayelement; import java.util.BitSet; public class MoveArrayElement { /** * 每次把数组中所有元素移动一个位置,移动k轮 * @param array * @param k */ public static void moveArrayElement(int[] array, int k) { int length =

【算法思想】循环移动一个数组

问题:如何将一个数组循环左移或者右移k位? 在下面的解决方案中,我们以循环左移为例. 我们最容易想到的是,将前k个元素复制到一个临时的数组中,然后将剩下的n-k个元素向左移动k个位置,然后将之前的k个元素复制到剩下的位置.这种方法使用了k个额外的存储空间.我们想到到另一种方法是,只借助一个临时空间,每次只向左移动1位,循环k次.这种方法产生了多于的运行时间.前面一篇文章中用程序实现了循环右移一个数组的算法.前面提到的都是比较常规的算法,下面从其它角度来考虑这一问题: 循环数组x其实就是交换数组x