首页 > 试题广场 >

假设有一个有 n 个元素的数组,求该数组右移 k 个元素后的

[问答题]

假设有一个有 n 个元素的数组,求该数组右移 k 个元素后的数组,要求算法的空间复杂度为 O(1)

输入数据右三行,第一行表示数组元素个数 n ,第二行表示数组,第三行表示 k

7

1,2,3,4,5,6,7

3

输出

5,6,7,1,2,3,4

思路是,从最后一位开始,找到它要填的位置,再去寻找那个位置的数的新位置,重复直到找到某个数的新位置为最后一位。
//右移数组
void moveArray(int arr[], int n,int k) {
k = k%n;
//取当前变换的一位,从最后一位开始
int currentIndex = n - 1, currentVal = arr[n - 1];
do {
//取到要变换的位置
currentIndex = (currentIndex + k) % n;
//交换当前值
int temp = arr[currentIndex];
arr[currentIndex] = currentVal;
currentVal = temp;
} while (n - 1 != currentIndex);
}
发表于 2017-08-08 19:14:44 回复(2)
  • 分享下我的思路:时间复杂度O(n),空间复杂度O(1)
  • 核心代码
    void rightMoveK(vector<int>& arr, int k)
    {
      int n = arr.size();
      if (n == 0)
          return;
      int i = 0;
      while (i < n-1)
      {
          int j = n - k;//每次都从n-k位置开始右移
          while (j < n)//每次右移k个数
          {
              swap(arr[j++], arr[i++]);//就地交换
          }
      }
    }
    思路解释:
  • 保证右移后的元素不需要再移动,所以从下标为n-k的元素开始右移k个元素,保证右移后的数字位于数组的最前面,并且不需要再移动
  • 每次右移,就是与下标为i的元素交换位置,一趟右移k个元素后, i 也前进了k个位置,不断的从n-k位置开始右移k个元素,直到 i 移动到数组尾部,此时整个数组右移完成
发表于 2020-05-03 09:59:06 回复(0)
两次翻转:
第一次:分别原地翻转数组的后k个元素和前n-k个元素;
第二次:原地翻转整个数组。
时间复杂度为O(n),空间复杂度O(1)。
发表于 2020-03-23 12:08:14 回复(0)
import java.util.Arrays;
import java.util.Scanner;

/**
 * @author: sanjin
 * @date: 2019/9/29 16:22
 */
public class Main {
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        int n = Integer.parseInt(s.nextLine());
        int[] nums = new int[n];
        String s1 = s.nextLine();
        for (int i = 0; i < n; i++) {
            nums[i] = Integer.parseInt(s1.split(",")[i]);
        }
        int k = Integer.parseInt(s.nextLine());
        for (int i = 0; i < k; i++) {
            shiftRightOnece(nums);
        }
        System.out.println(Arrays.toString(nums));
    }

    static void shiftRightOnece(int[] nums) {
        if (nums.length == 0) return;
        int t = nums[nums.length - 1];
        for (int i = nums.length - 2; i >= 0; i--) {
            nums[i + 1] = nums[i];
        }
        nums[0] = t;
    }
}

发表于 2019-09-29 16:29:39 回复(0)

代码比较睿智,时间复杂度较高,大概就是读取后,每次移动一个单位,移动k次 :(

    public void moveArray(int[] array, int k) {
        int temp;
        int i = 0;
        int j;
        for (; i < k; i++) {
            temp = array[array.length - 1];
            for (j = array.length - 1; j > 0; j--) {
                array[j] = array[j - 1];
            }
            array[0] = temp;
        }

    }
发表于 2019-03-05 18:40:20 回复(0)
#include <stdio.h>
int main(int argc, char *argv[])
{
    int a[10000], i,j,k,n,m;
    scanf("%d", &n);
    for (i = 0; i < n; i++){
        scanf("%d", &a[i]);
    }
    scanf("%d", &m);
    j = n + m;
    for (i = n - m; i <= j; i++){
        printf("%d", a[i >= n ? i - n: i]);
        if (i < j) {
            printf(",");
        }
    }
    
    return 0;
}



似乎符合题意吧,一开始看错成时间复杂度吓我一跳
编辑于 2018-03-12 17:03:27 回复(0)
#include<iostream>
#include<string>
#include<algorithm>

using namespace std;

int main()
{
    
    string str;
    int num;
    cin>>str;
    cin>>num;
    
    string::iterator it = str.begin();
    
    reverse(it,it+num);
    reverse(it+num,str.end());
    reverse(it,str.end());

    cout<<str<<endl;
    return 0;
}
哈哈哈   
发表于 2017-10-07 23:46:26 回复(0)
Lnz头像 Lnz
先预处理k,不能大于n。k = k%n;
然后对整个数组倒置。
再对0-(k-1)和k-(n-1)倒置。
输出结果
发表于 2017-09-03 00:08:31 回复(0)
1.利用一个临时变量可以完成
2.甚至不用临时变量也可以完成——加法:a=a+b;b=a-b;a=a-b;
                                                       异或法:a=a^b;b=b^a;a+a^b;
发表于 2017-08-09 14:32:38 回复(0)
public class Two { public static void main(String [] args){ int length; int pos;
         Scanner sc=new Scanner(System.in);
         length=sc.nextInt(); int [] num=new int[length]; for(int i=0;i<length;i++){
             num[i]=sc.nextInt();
         }
         pos=sc.nextInt(); // System.out.print(num[0]+num[6]);  GetPos(num,length,pos);
     } public static int[] GetPos(int [] A,int length,int pos){ int f=0,l=length-1; while(f<l){ int count=A[l];
             A[l]=A[f];
             A[f]=count;
             f++;
             l--;
         }
         f=0;l=length-1;int m=pos-1; while(f<m){ int count=A[m];
             A[m]=A[f];
             A[f]=count;
             f++;
             m--;
         } while(pos<l){ int count=A[pos];
             A[pos]=A[l];
             A[l]=count;
             pos++;
             l--;
         } // System.out.print(A[0]+A[6]);   for(int i=0;i<length;i++){
             System.out.print(A[i]);
        } return A;
     }
:注:代码比较繁琐,但是可以简化为一个函数,调用三次就可以啦(吧while部分提出来)
发表于 2017-03-11 13:58:47 回复(0)