编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
示例 1:
输入:s = [“h”,“e”,“l”,“l”,“o”]
输出:[“o”,“l”,“l”,“e”,“h”]
设置双指针,i指首,j指尾
void reverseString(char* s, int sSize) {
int i, j;
for(i=0, j=sSize-1; i<(int)(sSize/2); i++,j--){
char temp = s[i];
s[i] = s[j];
s[j] = temp;
}
}
给定长度为 2n 的整数数组 nums ,你的任务是将这些数分成 n 对, 例如 (a1, b1), (a2, b2), …, (an, bn) ,使得从 1 到 n 的 min(ai, bi) 总和最大。
返回该 最大总和 。
示例 2:
输入:nums = [6,2,6,5,1,2]
输出:9
解释:最优的分法为 (2, 1), (2, 5), (6, 6). min(2, 1) + min(2, 5) + min(6, 6) = 1 + 2 + 6 = 9
int sort(const void* a, const void* b) {
int q = *(int*)a;
int p = *(int*)b;
return q - p;
}
int arrayPairSum(int* nums, int numsSize) {
qsort(nums, numsSize, sizeof(int), sort);
int sum = 0 ;
int i, j;
for(i=0, j=1; j<numsSize; i+=2,j+=2){
sum += fmin(nums[i], nums[j]);
}
return sum;
}
从小到大排序,连续两两求min累加。
优化: 排序后求下标为偶数的和。
给你一个下标从 1 开始的整数数组 numbers ,该数组已按 非递减顺序排列 ,请你从数组中找出满足相加之和等于目标数 target 的两个数。如果设这两个数分别是 numbers[index1] 和 numbers[index2] ,则 1 <= index1 < index2 <= numbers.length 。
以长度为 2 的整数数组 [index1, index2] 的形式返回这两个整数的下标 index1 和 index2。
你可以假设每个输入 只对应唯一的答案 ,而且你 不可以 重复使用相同的元素。
你所设计的解决方案必须只使用常量级的额外空间
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* twoSum(int* numbers, int numbersSize, int target, int* returnSize) {
int* result = (int *)malloc(sizeof(int)*2);
int i=0, j= numbersSize-1;
bool flag=1;
while( i<numbersSize ,j>0 ){
if(numbers[i] + numbers[j] > target){
j--;
}
else if(numbers[i] + numbers[j] < target){
i++;
}
else{
break;
}
}
//printf("numbers[%d] : %d, numbers[%d] : %d\n", i, numbers[i], j, numbers[j]);
result[0] = i+1;
result[1] = j+1;
*returnSize = 2;
return result;
}
i指首,j指尾。 若n[i]+n[j] < target, i++; 若n[i]+n[j]>target, j–。
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
int removeElement(int* nums, int numsSize, int val) {
int fast= 0, slow=0;
while(fast<numsSize){
if(nums[fast] != val){
nums[slow] = nums[fast];
slow++;
}
fast++;
}
return slow;
}
使用快慢指针,快指针遍历数组,慢指针指向要填入的元素的位置,只有快指针指向的元素不等于目标值时,慢指针才能移动。
给定一个二进制数组 nums , 计算其中最大连续 1 的个数。
示例 1:
输入:nums = [1,1,0,1,1,1]
输出:3
解释:开头的两位和最后的三位都是连续 1 ,所以最大连续 1 的个数是 3.
int findMaxConsecutiveOnes(int* nums, int numsSize) {
int fast=0, slow=-1;
int sum =0;
while(fast < numsSize){
if(nums[fast]==0){
slow = fast;
}
fast++;
sum = fmax(sum, fast-slow-1);
}
return sum;
}
快指针遍历数组,当快指针指向0时,满指针才做移动,移动到快指针的位置。每次快指针移动时都记录长度:快指针-慢指针。对应连续1的个数。
给定一个含有 n 个正整数的数组和一个正整数 target 。
找出该数组中满足其总和大于等于 target 的长度最小的 连续子数组 [numsl, numsl+1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
示例 1:
输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。
int minSubArrayLen(int target, int* nums, int numsSize) {
int slow=0, fast=0;
int min = 0;
int sum=0;
for(fast=0; fast<numsSize; fast++){
sum = sum + nums[fast];
if(sum >= target){
while(sum - nums[slow] >= target){ //收缩慢指针的条件
sum = sum -nums[slow]; //收缩慢指针
slow++;
}
//min = (min===0)?(fast - slow + 1):fmin(min,fast - slow + 1);
if(min ==0){
min = (fast - slow + 1);
}
else{
min = fmin(min,fast - slow + 1);
}
//更新最小值,注意min为0时需要初始化min
}
}
return min;
}
慢指针指向区间前端, 快指针指向后端。
快指针先移动到大于目标值的位置,让慢指针收缩。