[初级算法]数组-旋转数组

Leetcode 189 旋转数组
题目:
给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。

示例 1:
输入: [1,2,3,4,5,6,7] 和 k = 3
输出: [5,6,7,1,2,3,4]
解释:
向右旋转 1 步: [7,1,2,3,4,5,6]
向右旋转 2 步: [6,7,1,2,3,4,5]
向右旋转 3 步: [5,6,7,1,2,3,4]

示例 2:
输入: [-1,-100,3,99] 和 k = 2
输出: [3,99,-1,-100]
解释: 
向右旋转 1 步: [99,-1,-100,3]
向右旋转 2 步: [3,99,-1,-100]

说明:
- 尽可能想出更多的解决方案,至少有三种不同的方法可以解决这个问题。
- 要求使用空间复杂度为 O(1) 的原地算法。
思路&实现:
// 第一版  时间复杂度O(n^2)
// 思路: 临时变量保存数组最后一个元素,然后整体前移,最后把临时变量赋给数组
//      首元素,连续循环k次就可以了。
// 执行用时:300 ms,超过36.56 %的c提交者
void rotate(int* nums, int numsSize, int k){
    for (int i = 0; i < k%numsSize; i++){
        int tmp = nums[numsSize-1];
        for (int j = numsSize-2; j >= 0; j--){
            nums[j+1]=nums[j];
        } 
        nums[0]=tmp;
    }
}

// 第二版  时间复杂度O(n) 空间复杂度O(1)
// 思路:分配一块大小为k*sizeof(int)的内存空间tmps,用来存放后数组中后k位元素。
//      将原始数组后k位数保存在tmps中,然后原始数组整体往后移k位,最后将tmps中
//      元素依次赋给原始数组前0~k位即可。
// 执行用时:8 ms,超过92.84 %的c提交者。
void rotate2(int* nums, int numsSize, int k){
    int p = 0;
    int n = k % numsSize; //对k取余,只需要旋转小于numsSize的长度
    int *tmps = (int *)malloc(n*sizeof(int));
    if (tmps == NULL){
        return;
    }
    for (int i = numsSize-n; i < numsSize; i++){
        tmps[p++] = nums[i];
    }
    for (int j = numsSize-1-n; j >= 0; j--){
        nums[j+n] = nums[j];
    }
    for (int m = 0; m < n; m++){
        nums[m] = tmps[m];
    }
    free(tmps);
    tmps = NULL;
}  
完整代码:
// 第一版
void rotate(int* nums, int numsSize, int k){
    for (int i = 0; i < k%numsSize; i++){
        int tmp = nums[numsSize-1];
        for (int j = numsSize-2; j >= 0; j--){
            nums[j+1]=nums[j];
        } 
        nums[0]=tmp;
    }
}

// 第二版
void rotate2(int* nums, int numsSize, int k){
    int p = 0;
    int n = k % numsSize; //对k取余,只需要旋转小于numsSize的长度
    int *tmps = (int *)malloc(n*sizeof(int));
    if (tmps == NULL){
        return;
    }
    for (int i = numsSize-n; i < numsSize; i++){
        tmps[p++] = nums[i];
    }
    for (int j = numsSize-1-n; j >= 0; j--){
        nums[j+n] = nums[j];
    }
    for (int m = 0; m < n; m++){
        nums[m] = tmps[m];
    }
    free(tmps);
    tmps = NULL;
}  


// 测试
void test(int* nums, int numsSize, int k, int* values){
    // rotate(nums, numsSize, k);
    rotate2(nums, numsSize, k);
    for(int i = 0; i < numsSize; i++){
        if (nums[i] != values[i]){
            printf("failure num:%d, value:%d\n", nums[i], values[i]);
            return;
        }
    }
    printf("success\n");
}

// main
void main(){
    int nums[7] = {1,2,3,4,5,6,7};
    int k = 3;
    int values[7] = {5,6,7,1,2,3,4};
    test(nums, 7, k, values);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值