Leetcode 560. 和为 K 的子数组和Leetcode 189. 轮转数组


Leetcode 560. 和为 K 的子数组

题目描述

给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的子数组的个数 。

子数组是数组中元素的连续非空序列。

示例 1:

输入:nums = [1,1,1], k = 2
输出:2

示例 2:

输入:nums = [1,2,3], k = 3
输出:2

提示:

  • 1 <= nums.length <= 2 * 10 ^ 4
  • -1000 <= nums[i] <= 1000
  • -10 ^ 7 <= k <= 10 ^ 7

C语言题解和思路

int subarraySum(int* nums, int numsSize, int k) {
    int ret = 0, sum = 0;
    int i = 0, j = 0;
    int a = 10000000;
    int hash[20000000] = {0};
    hash[0 + a] = 1;
    for(i = 0; i < numsSize; i++)
    {
        sum += nums[i];
        if(hash[sum + a - k] != 0)
        {
            ret += hash[sum - k + a];
        }
        hash[sum + a]++;
    }
    return ret;
}

解题思路

哈希表 + 前缀和:
如果数组前 i 个值的和与数组前 j 个值的和的差等于 k ,说明下标 i-1 到 j-1 的子数组的和为 k 。

定义一个有2*10^7的数组作为哈希表,并初始化为0。

定义变量 a 并声明为 10^7 ,因为 k 的值包含负数,而数组的下标从 0 开始,所以设置将 a 的值作为数字 0 的位置。

将数字 0 的位置赋值 1 ,表示当子数组的和等于 k 后使返回值加的量。

遍历数组,让变量 sum 加上各个下标的值,判断 sum 与 k 的差的位置是否为 0 ,如果不为 0 ,让返回值加上哈希表上该位置的值;判断完后让哈希表 sum 上的值加 1 。

遍历完后,返回 ret 。

Leetcode 189. 轮转数组

题目描述

给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。

示例 1:

输入: nums = [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:

输入:nums = [-1,-100,3,99], k = 2
输出:[3,99,-1,-100]
解释:
向右轮转 1 步: [99,-1,-100,3]
向右轮转 2 步: [3,99,-1,-100]

提示:

  • 1 <= nums.length <= 10^5
  • -2 ^ 31 <= nums[i] <= 2 ^ 31 - 1
  • 0 <= k <= 10^5

进阶:

尽可能想出更多的解决方案,至少有 三种 不同的方法可以解决这个问题。
你可以使用空间复杂度为 O(1) 的 原地 算法解决这个问题吗?

C语言题解和思路

void rotate(int* nums, int numsSize, int k) {
    k = k % numsSize;
    int *tmp = (int *)malloc(sizeof(int) * (k + 1));
    int i, j = 0, c;
    for(i = numsSize - k; i < numsSize; i++)
    {
        tmp[j++] = nums[i];
    }
    j = numsSize - 1;
    for(i = numsSize - k - 1; i >= 0; i--)
    {
        nums[j--] = nums[i];
    }
    for(i = 0; i < k; i++)
    {
        nums[i] = tmp[i];
    }
}

解题思路

如果 k 大于数组的长度,需要取 k 除以数组长度的余数,否则会重复轮转。

将数组后 k 个元素保存在一个临时数组中,将原数组 nums 的元素往后挪 k 位。

再将临时数组中的数转移回原数组的前 k 位。

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值