leetcode 初级之数组篇 03

旋转数组

给定一个数组,将数组中的元素向右移动 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]

方法一

// 性能较差劲
//void rotate(int* nums, int numsSize, int k) {
//    int tem = 0;
//    for (int i = 1; i <= k; i++) {
//        tem = nums[numsSize - 1];
//        for (int j = numsSize - 1; j >= 0; j--) {
//            nums[j] = nums[j - 1];
//        }
//        nums[0] = tem;
//    }
//}

方法二

// 执行用时 4ms 高效算法
void reverse(int *arr, int start, int end) {
    int temp = 0;
    while (start < end) {
        temp = arr[start];
        arr[start] = arr[end];
        arr[end] = temp;
        start++;
        end--;
    }
}

void rotate(int* nums, int numsSize, int k) {
    if (nums == NULL || numsSize == 0 || k % numsSize == 0) {
        return;
    }
    int kcount = k % numsSize;
    int middle = numsSize - kcount;
    reverse(nums, 0, middle - 1); // reverse left part
    reverse(nums, middle, numsSize - 1); // reverse right part
    reverse(nums, 0, numsSize - 1); // reverse whole part
}
int main(int argc, const char * argv[]) {
    @autoreleasepool {
     
        int arr[] = {1,2,3,4,5,6,7};
        rotate(arr, 7, 3);
        for (int i = 0; i < 7; i++) {
            printf("%d ",arr[i]);
        }
        printf("\n");
    }
    return 0;
}

这里有一个很巧妙的方法:

利用数组的length - k 把数组 分为两半;

reverse 左边和右边的数组;

reverse 总数组。

举一个例子:

1 2 3 4 5 6 7  如果k = 3 的话, 会变成 5 6 7 1 2 3 4

1 2 3 4 5 6 7  middle = 7 - 3 = 4,分为左边 4个数字,右边 3个数字

4 3 2 1 7 6 5  分别把左右reverse 一下

5 6 7 1 2 3 4  把总数组reverse 一下就会得到答案

参考文章:
http://www.cnblogs.com/grandyang/p/4298711.html
http://www.cnblogs.com/grandyang/p/4298711.html

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容