剑指offer (41) 有序数组数字之和

题目:输入一个递增排序的数组和一个数字target,在数组中查找两个数使得它们的和正好是target

题解分析:

一提到有序数组,应该立马联想到 二分查找

因为数组已经有序了,我们可以设置两个游标first和last,下标first指向 0, last指向 size() - 1, 然后相加

如果 相加和 大于 target,last--

如果 相加和 小于 target,first++

T(n) = O(n)

void TwoSum(const std::vector<int>& num, int target, std::vector<std::vector<int>>& result) {
    if (num.size() < 2) return;

    int first = 0;
    int last  = num.size() - 1;
    while (first < last) {
        int sum = num.at(first) + num.at(last);
        if (sum < target) {
            ++first;
        } else if (sum > target) {
            --last;
        } else {
            std::vector<int> tmp = {num.at(first), num.at(last)};
            result.push_back(tmp);
            ++first;
            --last;
        }
    }
}

题目二:输入一个正整数s,打印出所有和为s的连续整数序列(至少含两个数)

例如 target = 15:

1+2+3+4+5

4+5+6

7+8

题解分析:

step1. 分别使用两个游标指示 当前序列的最小值和最大值,即 first游标指示 当前序列的第一个数,last游标指示 当前序列的最后一个数

step2. sum = first + last

step3.

如果 sum < target, 则需要last向右扩充一步使得当前序列和增大,即先++last,然后更新sum

如果 sum > target, 则需要first向右扩充一步使得当前序列和减小,这时需要先更新sum,然后--first

void Sum(int target, std::vector<std::vector<int>>& result)
{
    int first = 1;
    int last  = 2;
    int sum = first+ last;
    while (first < last && first <= target / 2) {
        if (sum < target) {
            ++last;
            sum += last;
        } else if (sum > target) {
            sum -= first;
            ++first;
        } else {
            std::vector<int> temp(last - first + 1, 0);
            for (int i = 0; i < last - first + 1; ++i) {
                temp.at(i) = (first + i);
            }
            result.push_back(temp);
            ++last;
            sum += last;
        }
    }
}

剑指offer (41) 有序数组数字之和

时间: 2024-10-08 03:52:32

剑指offer (41) 有序数组数字之和的相关文章

【剑指offer】Q38:数字在数组中出现的次数

与折半查找是同一个模式,不同的是,在这里不在查找某个确定的值,而是查找确定值所在的上下边界. def getBounder(data, k, start, end, low_bound = False): if end < start : return -1 while start <= end: mid = ( start + end ) >> 1 if data[ mid ] > k: end = mid - 1 elif data[ mid ] < k: star

【剑指offer】旋转数组的最小数字

题目描述: 把一个数组最开始的若干个元素搬到数组的末尾,称之为数组的旋转.输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素.例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1. 分析描述: 求一个数组中的最小值,最简单的办法就是逐个比较数组中各个元素的值,遍历完整个数组,即可得数组中最小元素.但这种方法存在的问题是时间复杂度为O(n). 利用题目中给出的条件:递增排序数组的旋转.利用递增排序的特点,可以用二分查找方法实现时间复杂度为O(logn)的查找.

剑指OFFER之旋转数组的最小数字(九度OJ1386)

题目描述: 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素.例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1. 输入: 输入可能包含多个测试样例,对于每个测试案例, 输入的第一行为一个整数n(1<= n<=1000000):代表旋转数组的元素个数. 输入的第二行包括n个整数,其中每个整数a的范围是(1<=a<=10000000). 输出: 对应每个测试案例, 输出旋转数组

剑指Offer:旋转数组的最小数字【11】

剑指Offer:旋转数组的最小数字[11] 题目描述 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素. 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1. NOTE:给出的所有元素都大于0,若数组大小为0,请返回0. 解题分析 我们用两个坐标,Left,Right分别表示左右两个递增序列的下标,刚开始L为0,R为4: 当Arr[Mid]>Arr[Left],可以说明,Mid及左边构

剑指Offer 11. 旋转数组的最小数字

12345678910111213141516171819202122232425262728293031323334353637383940414243 public class { public int minNumberInRotateArray(int[] array) { int index1 = 0; int index2 = array.length - 1; int indexMid = 0; if (array.length == 0) { return 0; } while

[剑指Offer]41 和为S的两个数字 VS 和为S的连续正数序列

[剑指Offer]41 和为S的两个数字 VS 和为S的连续正数序列 Leetcode T1 Two Sum Given an array of integers, return indices of the two numbers such that they add up to a specific target. You may assume that each input would have exactly one solution, and you may not use the s

剑指OFFER之调整数组顺序使奇数位于偶数前面找(九度OJ1516)

题目描述: 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变. 输入: 每个输入文件包含一组测试案例.对于每个测试案例,第一行输入一个n,代表该数组中数字的个数.接下来的一行输入n个整数.代表数组中的n个数. 输出: 对应每个测试案例,输入一行n个数字,代表调整后的数组.注意,数字和数字之间用一个空格隔开,最后一个数字后面没有空格. 样例输入: 5 1 2 3 4 5 样例输

【剑指offer】旋转数组中的最小值

题目总结: 1.若没有进行旋转,或者说旋转后的效果跟没有旋转是一样的,那么index1指示的值小于index2指示的值,返回index1的值. 2.若是一般性的旋转,那么最小的值旋转后肯定在中间,那么我们就可以从两边向中间夹逼. 3.夹逼的过程中,若 [ index1, middle ] 是有序的,说明这部分子区间没被破坏,旋转所移动的元素都在middle 的后面,那么最小值可定也在后面的部分,令 index1 = middle,继续向后夹逼:同理,若 [ middle ,index2 ] 是有

剑指OFFER之把数组排成最小的数(九度OJ1504)

题目描述: 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个.例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323. 输入: 输入可能包含多个测试样例.对于每个测试案例,输入的第一行为一个整数m (1<=m <=100)代表输入的正整数的个数.输入的第二行包括m个正整数,其中每个正整数不超过10000000. 输出: 对应每个测试案例,输出m个数字能排成的最小数字. 样例输入: 3 23 13 6 2 23456 56 样