🌈你好呀!我是 山顶风景独好
💝欢迎来到我的博客,很高兴能够在这里和您见面!
💝希望您在这里可以感受到一份轻松愉快的氛围!
💝不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。
🚀 欢迎一起踏上探险之旅,挖掘无限可能,共同成长!
189. 轮转数组
给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。
思路如下:
- 首先对整个数组实行翻转,这样子原数组中需要翻转的子数组,就会跑到数组最前面。
- 这时候,从 kkk 处分隔数组,左右两数组,各自进行翻转即可。
class Solution {
// 旋转数组的方法
public void rotate(int[] nums, int k) {
// 如果k大于数组长度,则通过取模操作减少k的值,因为轮转长度超过数组长度是无效的
k %= nums.length;
// 首先将整个数组反转
reverse(nums, 0, nums.length - 1);
// 然后将前k个元素反转,得到原本的后k个元素在正确位置上的结果
reverse(nums, 0, k - 1);
// 最后将剩下的元素(即原数组中的前n-k个元素)反转,得到最终的轮转结果
reverse(nums, k, nums.length - 1);
}
// 反转数组指定区间内元素的方法
// 参数start表示区间的起始索引,end表示区间的结束索引(不包含end)
public void reverse(int[] nums, int start, int end) {
// 当起始索引小于结束索引时,进行反转操作
while (start < end) {
// 交换start和end索引处的元素
int temp = nums[start];
nums[start] = nums[end];
nums[end] = temp;
// 起始索引和结束索引分别向中间移动
start += 1;
end -= 1;
}
}
}
122. 买卖股票的最佳时机 II
- 给你一个整数数组 prices ,其中 prices[i] 表示某支股票第 i 天的价格。
- 在每一天,你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买,然后在 同一天 出售。
- 返回 你能获得的 最大 利润 。
思路如下:
该问题的核心是在给定的股票价格数组中,找出可以执行多次买卖操作(即同一天内可以买入并卖出)以获得最大利润的方式。由于可以多次买卖,所以只要股票的价格在连续两天中是上涨的,就可以在第一天买入并在第二天卖出以获取利润。
class Solution {
public int maxProfit(int[] prices) {
// 初始化最大利润为0
int res = 0;
// 遍历价格数组,从索引1开始(因为我们需要比较当前价格与前一天的价格)
for (int i = 1; i < prices.length; i++) {
// 如果当前价格比前一天的价格高,说明我们可以买入前一天的价格并在今天卖出以获取利润
if (prices[i] - prices[i - 1] > 0) {
// 将这个利润累加到最大利润中
res += prices[i] - prices[i - 1];
}
}
// 返回最大利润
return res;
}
}
55. 跳跃游戏
- 给你一个非负整数数组 nums ,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。
- 判断你是否能够到达最后一个下标,如果可以,返回 true ;否则,返回 false 。
class Solution {
public static boolean canJump(int[] nums) {
// 初始化一个变量k,用于表示当前能够到达的最远位置
int k = 0;
// 遍历数组中的每一个元素
for (int i = 0; i < nums.length; i++) {
// 如果当前位置i已经超过了能够到达的最远位置k,那么就无法继续跳跃,返回false
if (i > k) return false;
// 更新能够到达的最远位置k,取当前能够到达的最远位置k和当前位置i加上当前位置能够跳跃的最大长度nums[i]的较大值
k = Math.max(k, i + nums[i]);
// 如果在遍历过程中,k能够到达或超过数组的最后一个位置,那么说明能够到达最后一个位置,但此处不需要立即返回true
// 因为我们需要遍历完整个数组,以确保没有其他位置无法到达
}
// 如果遍历完整个数组都没有返回false,那么说明能够到达最后一个位置,返回true
return true;
}
}
45. 跳跃游戏 II
- 给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。
- 每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说,如果你在 nums[i] 处,你可以跳转到任意 nums[i + j] 处:
- 0 <= j <= nums[i]
- i + j < n
- 返回到达 nums[n - 1] 的最小跳跃次数。生成的测试用例可以到达 nums[n - 1]。
class Solution {
public int jump(int[] nums) {
// 获取数组的长度
int length = nums.length;
// end表示当前步跳跃可以到达的最远位置
int end = 0;
// maxPosition表示从当前位置起跳能够到达的最远位置
int maxPosition = 0;
// steps记录跳跃的次数
int steps = 0;
// 遍历数组,除了最后一个位置(因为最后一个位置不需要跳跃到达)
for (int i = 0; i < length - 1; i++) {
// 更新从当前位置起跳能够到达的最远位置
maxPosition = Math.max(maxPosition, i + nums[i]);
// 如果当前位置i是当前步跳跃可以到达的最远位置
if (i == end) {
// 更新当前步跳跃可以到达的最远位置为maxPosition
end = maxPosition;
// 跳跃次数加1
steps++;
}
}
// 当遍历完数组后,steps就是到达数组最后一个位置所需的最少跳跃次数
return steps;
}
}
274. H 指数
- 给你一个整数数组 citations ,其中 citations[i] 表示研究者的第 i 篇论文被引用的次数。计算并返回该研究者的 h 指数。
- 根据维基百科上 h 指数的定义:h 代表“高引用次数” ,一名科研人员的 h 指数 是指他(她)至少发表了 h 篇论文,并且 至少 有 h 篇论文被引用次数大于等于 h 。如果 h 有多种可能的值,h 指数 是其中最大的那个。
示例 1:
- 输入:citations = [3,0,6,1,5]
- 输出:3
- 解释:给定数组表示研究者总共有 5 篇论文,每篇论文相应的被引用了 3, 0, 6, 1, 5 次。
由于研究者有 3 篇论文每篇 至少 被引用了 3 次,其余两篇论文每篇被引用 不多于 3 次,所以她的 h 指数是 3。
示例 2:
- 输入:citations = [1,3,1]
- 输出:1
class Solution {
public int hIndex(int[] citations) {
// 初始化左右指针,左指针指向数组开始,右指针指向数组末尾的下一个位置(因为数组索引是从0开始的)
int left = 0, right = citations.length;
// mid 用于存储二分查找的中间索引
int mid = 0, cnt = 0;
// 当左指针小于右指针时,进行二分查找
while (left < right) {
// 计算中间索引,注意这里使用 (left + right + 1) >> 1 而不是 (left + right) / 2
// 这样做是为了在 right - left 为奇数时,mid 偏向右侧,防止在 left 和 right 相邻时陷入死循环
mid = (left + right + 1) >> 1;
cnt = 0; // 重置计数,用于统计被引用次数大于等于 mid 的论文数量
// 遍历数组,统计被引用次数大于等于 mid 的论文数量
for (int i = 0; i < citations.length; i++) {
if (citations[i] >= mid) {
cnt++;
}
}
// 如果被引用次数大于等于 mid 的论文数量大于等于 mid,则 h 指数至少为 mid
// 更新 left 指针为 mid,继续在 [mid, right) 范围内查找可能的更大的 h 指数
if (cnt >= mid) {
left = mid;
// 否则,h 指数一定小于 mid,更新 right 指针为 mid - 1,继续在 [left, mid - 1] 范围内查找
} else {
right = mid - 1;
}
}
// 循环结束后,left 和 right 指针重合,left(或 right)就是要求的 h 指数
return left;
}
}