二分查找
#include <stdio.h>
int binarySearch(int* nums, int numsSize, int target) {
int left = 0;
int right = numsSize - 1;
while (left <= right) {
int mid = left + (right - left) / 2; // 防止整数溢出
if (nums[mid] == target) {
return mid; // 找到目标值,返回下标
} else if (nums[mid] < target) {
left = mid + 1; // 目标值在右半部分
} else {
right = mid - 1; // 目标值在左半部分
}
}
return -1; // 未找到目标值,返回 -1
}
int main() {
int nums[] = {1, 3, 5, 7, 9, 11};
int target = 7;
int result = binarySearch(nums, sizeof(nums)/sizeof(nums[0]), target);
if (result != -1) {
printf("Found target %d at index %d\n", target, result);
} else {
printf("Target %d not found\n", target);
}
return 0;
}
#include <stdio.h>
int binarySearch(int* nums, int numsSize, int target) {
int left = 0;
int right = numsSize; // 右边界初始为数组大小,而不是 numsSize - 1
while (left < right) { // 循环条件改为 left < right
int mid = left + (right - left) / 2;
if (nums[mid] == target) {
return mid; // 找到目标值,返回下标
} else if (nums[mid] < target) {
left = mid + 1; // 目标值在右半部分,更新左边界
} else {
right = mid; // 目标值在左半部分,更新右边界,不减1
}
}
return -1; // 未找到目标值,返回 -1
}
int main() {
int nums[] = {1, 3, 5, 7, 9, 11};
int target = 7;
int result = binarySearch(nums, sizeof(nums)/sizeof(nums[0]), target);
if (result != -1) {
printf("Found target %d at index %d\n", target, result);
} else {
printf("Target %d not found\n", target);
}
return 0;
}
长度最小的子数组
这是一个经典的滑动窗口问题,目的是在数组中找到满足条件的最小连续子数组长度。我们可以通过滑动窗口来高效解决这个问题。
解题思路
-
滑动窗口定义:
- 滑动窗口通常用于处理连续子数组或子字符串的问题。通过调整窗口的起始位置和结束位置,我们可以控制当前子数组的范围。
-
问题分析:
- 我们需要找到一个子数组,使得这个子数组的和至少等于给定的正整数
s
,并且这个子数组的长度是所有满足条件的子数组中最小的。
- 我们需要找到一个子数组,使得这个子数组的和至少等于给定的正整数
-
滑动窗口的使用:
- 我们初始化窗口的起始位置
left
和结束位置right
都为0
,以及一个变量currentSum
来记录当前窗口内的数字和。 - 我们逐步扩大窗口(移动
right
),每次增加nums[right]
到currentSum
中。 - 当
currentSum
大于或等于s
时,我们尝试缩小窗口(移动left
),并更新最小长度。 - 这个过程一直持续到
right
遍历完数组。
- 我们初始化窗口的起始位置
-
结果判断:
- 如果在整个过程中未找到满足条件的子数组,则返回
0
。#include <stdio.h> int minSubArrayLen(int s, int* nums, int numsSize) { int left = 0; // 窗口的左边界 int currentSum = 0; // 当前窗口内的数字和 int minLength = numsSize + 1; // 初始化最小长度为一个不可能的最大值 for (int right = 0; right < numsSize; right++) { currentSum += nums[right]; // 扩大窗口,包含nums[right] // 尝试缩小窗口 while (currentSum >= s) { int currentLength = right - left + 1; // 当前窗口长度 if (currentLength < minLength) { minLength = currentLength; // 更新最小长度 } currentSum -= nums[left]; // 缩小窗口,去掉nums[left] left++; // 移动左边界 } } // 如果 minLength 没有被更新,说明没有满足条件的子数组,返回 0 return minLength == numsSize + 1 ? 0 : minLength; } int main() { int nums[] = {2, 3, 1, 2, 4, 3}; int s = 7; int result = minSubArrayLen(s, nums, sizeof(nums)/sizeof(nums[0])); if (result != 0) { printf("The minimal length of a subarray with sum >= %d is %d\n", s, result); } else { printf("There is no subarray with sum >= %d\n", s); } return 0; }
- 如果在整个过程中未找到满足条件的子数组,则返回