[算法] 原地哈希算法(Java)

本文详细讲解了原地哈希算法在Java中的实现,重点介绍了如何利用数组作为哈希表,并通过LeetCode 448题为例,展示了其在有限范围内的应用。适合理解数组下标作为哈希值的情况。

[算法] 原地哈希算法(Java)

1.定义

原地哈希算法是指将原数组当成哈希表, 不开辟额外空间.

2.适用条件

原数组总所有数字范围都不超过数组长度, 也就是,给定一个数组nums, 原地哈希应用范围为[0, nums.length], 将数组元素本身作为nums的下标,也就是, nums[nums[i]].

3.举个栗子

LeetCode 448题

数组的原地旋转算法可以通过翻转数组的方式高效实现。这种方法的核心思想是通过三次翻转操作,将数组中的元素移动到正确的位置。具体步骤如下: 1. **翻转整个数组**:这一步会将尾部的 `k % n` 个元素移到数组的前面。 2. **翻转前 `k % n` 个元素**:这一步会将之前翻转的前 `k % n` 个元素恢复顺序。 3. **翻转剩余的元素**:这一步会将后半部分的元素恢复顺序。 以下是实现代码: ```c #include <stdio.h> // 交换两个整数 void swap(int* a, int* b) { int t = *a; *a = *b; *b = t; } // 翻转数组的指定区间 void reverse(int* nums, int start, int end) { while (start < end) { swap(&nums[start], &nums[end]); start += 1; end -= 1; } } // 旋转数组 void rotate(int* nums, int numsSize, int k) { k %= numsSize; // 防止k大于数组长度 // 第一次翻转整个数组 reverse(nums, 0, numsSize - 1); // 第二次翻转前k个元素 reverse(nums, 0, k - 1); // 第三次翻转剩下的元素 reverse(nums, k, numsSize - 1); } // 测试代码 int main() { int nums[] = {1, 2, 3, 4, 5, 6, 7}; int numsSize = sizeof(nums) / sizeof(nums[0]); int k = 3; // 旋转3次 printf("原始数组: "); for (int i = 0; i < numsSize; i++) { printf("%d ", nums[i]); } rotate(nums, numsSize, k); printf("\n旋转后的数组: "); for (int i = 0; i < numsSize; i++) { printf("%d ", nums[i]); } return 0; } ``` ### 关键点说明 - **时间复杂度**:三次翻转操作的时间复杂度均为 $O(n)$,因此整体时间复杂度为 $O(n)$。 - **空间复杂度**:该算法原地进行的,没有使用额外的空间,因此空间复杂度为 $O(1)$。 - **适用场景**:适用于需要高效旋转数组的情况,尤其是当数组长度较大时。 ### 示例输出 ``` 原始数组: 1 2 3 4 5 6 7 旋转后的数组: 5 6 7 1 2 3 4 ``` 这种方法通过巧妙地利用翻转操作,避免了额外的空间占用,同时保持了高效的执行速度。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值