代码随想录62——额外题目【数组】:189轮转数组、724寻找数组的中心下标、922按奇偶排序数组II
创始人
2024-02-07 18:26:02
0

文章目录

  • 1.189轮转数组
    • 1.1.题目
    • 1.2.解答
  • 2.724寻找数组的中心下标
    • 2.1.题目
    • 2.2.解答
  • 3.922按奇偶排序数组II
    • 3.1.题目
    • 3.2.解答

1.189轮转数组

参考:代码随想录,189轮转数组;力扣题目链接

1.1.题目

在这里插入图片描述

1.2.解答

这道题目在字符串里其实很常见,我把字符串反转相关的题目列一下:

字符串:力扣541.反转字符串II、字符串:力扣151.翻转字符串里的单词、字符串:剑指Offer58-II.左旋转字符串

本题其实和字符串:剑指Offer58-II.左旋转字符串 就非常像了,剑指offer上左旋转,本题是右旋转。

注意题目要求是要求使用空间复杂度为 O(1) 的 原地 算法

原地左边旋转字符串

  • 反转区间为前n的子串
  • 反转区间为n到末尾的子串
  • 反转整个字符串

原地右边旋转字符串

  • 反转整个字符串
  • 反转区间为前k的子串
  • 反转区间为k到末尾的子串

需要注意的是,本题还有一个小陷阱,题目输入中,如果k大于nums.size了应该怎么办

其实移动到num.size()次数之后就相当于没有移动,所以直接执行k % nums.size()次数就行。

最后给出代码如下,注意是右旋转,所以要先旋转整个字符串,再旋转子串。

void rotate(vector &nums, int k)
{k = k % nums.size();   // 防止k过大// 左移:先旋转子串,再旋转整个字符串;右移:先旋转子串,再旋转整个字符串reverse(nums.begin(), nums.end());          // 先旋转整个数组reverse(nums.begin(), nums.begin() + k);    // 在旋转前半部分reverse(nums.begin() + k, nums.end());  // 最后旋转后半部分
}

2.724寻找数组的中心下标

参考:代码随想录,724寻找数组的中心下标;力扣题目链接

2.1.题目

在这里插入图片描述

2.2.解答

首先注意不要把这道题目理解错了,其中说的左右相等的下标是不包括当前的数字的,而是不算当前数字,其左边的数字和右边的数字的和相等。

但是这道题目仍然非常简单:

  • 遍历一遍求出总和sum
  • 遍历第二遍求中心索引左半和leftSum
    同时根据sum和leftSum 计算中心索引右半和rightSum
    判断leftSum和rightSum是否相同

给出代码如下:

int pivotIndex(vector &nums)
{// 1.统计和int sum = 0;for(const auto& num : nums)sum += num;int left_sum = 0;int right_sum = 0;// 2.遍历求左边的和 和 右边的和for(int i = 0; i < nums.size(); i++){// 注意这个并不是真的left_sum,而是多加了nums[i]left_sum += nums[i];  // 所以这里right_sum就也要把nums[i]加上right_sum = sum - left_sum + nums[i];  if(left_sum == right_sum)return i;}// 运行到这里说明没找到,返回-1return -1;
}

注意:上述代码就是在计算过程中,遍历到当前的下标时,直接把左边的left_sum也加上了当前的nums[i],此时i右边的数字综合是sum - left_sum。但是由于我们的left_sum多加了nums[i],所以这里计算right_sum的时候也要多加nums[i],即right_sum = sum - left_sum + nums[i]。比如1 7 3 6 5 6的例子,便利到6的时候,左边和是11,但是此时left_sum = 17,因为多加了当前的6;此时右边和是11,所以也要多加上当前的6,结果也是17.

另外一个方法其实就是可以便利到当前数字之后,就从总和中减去当前的数字,然后再/2,看结果和左边的和是否相等。此时的代码如下:

int pivotIndex(vector &nums)
{   // 1.计算总和int sum = 0;for(const auto& num : nums)sum += num;int left_sum = 0;   // 左边总和,不包括当前下标for(int i = 0; i < nums.size(); i++){// 如果此时总和/2等于左边的和if(left_sum * 2 == sum - nums[i])   return i;else left_sum += nums[i];   // 否则累加当前数字,给下一次准备}// 运行到这里说明没找到,返回-1return -1;
}

3.922按奇偶排序数组II

参考:代码随想录,922按奇偶排序数组II;力扣题目链接

3.1.题目

在这里插入图片描述

3.2.解答

这道题目直接的想法可能是两层for循环再加上used数组表示使用过的元素,这样的的时间复杂度是O(n^2)。

但是其实可以换一个角度想,建立一个结果数组,分别分成奇数索引的空位和偶数索引的空位。然后遍历原数组中的元素,如果是奇数,那么就填到奇数空位中;如果是偶数,就填到偶数索引的空位中,这样就很简单了。

直接给出代码如下:

vector sortArrayByParityII(vector &nums)
{vector result(nums.size(), 0);   // 先构造存储结果的数组int odd_idx = 1;   // 初始化奇数和偶数索引int even_idx = 0;   for(const auto& num : nums){if(num % 2 == 0)   // 偶数{result[even_idx] = num;even_idx += 2;}else   // 奇数{result[odd_idx] = num;odd_idx += 2;}}return result;
}

相关内容

热门资讯

安全教育名言   安全教育名言  1、查隐患及时整改不马虎,纠违章严肃处理不放过。  2、穿马路是左右看,用家电是...
保尔的名言 保尔的名言  1、一个人的生命应当这样度过:当他回首往事的时候不会因虚度年华而悔恨,也不会因碌碌无为...
诚信的名言 有关诚信的名言15篇  在日常的学习、工作、生活中,大家最不陌生的就是名言了吧,名言主要用来激励和告...
环保的名言名句 环保的名言名句  在平平淡淡的日常中,大家总免不了要接触或使用名言吧,在议论文中,引用名言,不但体现...
自强不息的名言名句 自强不息的名言名句  自强不息的名言名句【经典篇】  1、生活的目标,是唯一值得寻找的财富。——史蒂...
教师人生格言大全   教师人生格言大全    1、 教师如果对学生没有热情,决不能成为好教师。但是教师对于学生的爱是一...
简短的人生格言 简短的人生格言集锦55句  人假使没有自尊心,那就会一无价值。——[俄国]屠格涅夫以下是小编为大家推...
谦虚的名言 谦虚的名言  谦虚的名言  在日常学习、工作或生活中,说到名言,大家肯定都不陌生吧,名言可以带来警醒...
珍爱生命的名人名言 珍爱生命的名人名言(精选55句)  关于生命的名人名言有哪些?生命,值得我们尊重,你知道哪些关于生命...
关于知音的名言名句  导语:关于知音或者是友谊的古诗词, 名人名言,这里全都有,关于知音的名言名句。  君子之交淡若水,...
清正廉洁格言 清正廉洁格言最短的人生格言1、执政以廉为本,为官以勤为先。2、做人一身正气,为官一尘不染。3、名位利...
罗素名言 罗素名言69句  1、伟大的事业是根源于坚韧不断的工作,以全付精神去从事,不避艰苦。——罗素  2、...
朋友的名人名言 有关朋友的名人名言汇总  在学习、工作、生活中,大家都不可避免地会接触并使用名言吧,名言可以用来鞭策...
乔布斯名言经典摘抄 乔布斯名言经典摘抄  乔布斯出生于美国加利福尼亚州旧金山,美国发明家、企业家、美国苹果公司联合创办人...
夺眶而出的名言名句 关于夺眶而出的名言名句  这里是郁郁葱葱的山神之森,一定,要有一段时间无法再盼望夏天了,心如刀绞,泪...
信仰名言 精选关于信仰名言  关于信仰名言  1、没有信仰的人如同盲人(弥顿)  2、有信仰未必能成大事,而没...
告诉自己珍惜时间的名言名句 志士惜年,贤人惜日,圣人惜时,告诉自己珍惜时间的名言名句。圣人都珍惜时间,我们凡人更要珍惜时间。下面...
工匠精神的名人名言 关于工匠精神的名人名言  1、最佳的创新定义是“不限大小,不限部门”。 最有效的创新都简单得惊人,其...
青春奋斗的名言警句 关于青春奋斗的名言警句1、青春是美妙的,挥霍青春就是犯罪,关于青春奋斗的名言警句。——萧伯纳  2、...
理想的阶梯 理想的阶梯理想的阶梯[教学目标]1.通过学习本文,使学生懂得“奋斗,是实现理想的阶梯”这一道理,并能...