返回数组中元素之和为输入值的元素的下标(以1为基)

Leetcode中原题:Two Sum

给定一个整数数组,找出其中和等于给定目标值的数的下标(数组第一个元素的下标是1),第一个下标必须比第二个下标小,假定此题只有唯一解。

例:

输入:numbers={2, 7, 11, 15}, target=9

输出:index1=1, index2=2

思路1:两层循环,外层循环从0到倒数第二个元素,里层循环,从当前外层循环下标的下一个值开始一直到数组结尾,复杂度O(n2),超时。

思路2:如果数组是有序的,显然有更好的做法。使用常用的效率比较高的排序算法,归并排序,堆排序等,时间复杂度为O(nlogn). 因为我们需要记录原始数组中的下标,所以不能在原始数组上进行排序,需要拷贝原始数组,在拷贝数组上进行排序。排完序后需要做两件事:

1)找出和为目标值的两个元素

2)找出这两个元素在原始数组中的下标。

其中,操作1)设定两个指针,分组指向数组的头部和尾部,计算指针所指值的和,如果两者之和大于目标值,则将尾部指针前移,如果两者之和小于目标值,则将首部指针后移,这样找到所求元素的时间复杂度是O(n)。

操作2)只需要遍历原始数组一遍,就可以求得相应下标,对应的时间复杂度为O(n)。

综合以上求解过程,整的时间复杂度为O(nlogn)+O(n)+O(n)=O(nlogn).

源代码如下:

class Solution {
public:
    vector<int> twoSum(vector<int> &numbers, int target) {
        vector<int> temp(numbers);
        vector<int> ret;
        merge_sort(temp,0,temp.size()-1); // 对拷贝数组进行归并排序
        int i = 0,j=temp.size()-1,k;
        int temp_first,temp_second;  // 记录所求元素值的临时变量        // 查找排序后数组中满足和为目标值的元素
        while(i<j)
        {
            if((temp[i]+temp[j])<target)
            {
                i++;
            }
            else if((temp[i]+temp[j])>target)
            {
                j--;
            }
            else
            {
                temp_first = temp[i];
                temp_second = temp[j];
                break;
            }
        }
        k=0;        // 遍历原始数组,找出相应元素的下标
        for(k;k!=numbers.size();k++)
        {
            if(numbers[k]==temp_first||numbers[k]==temp_second)
            {
                ret.push_back(k+1);
            }
        }
        return ret;
    }
    void merge_sort(vector<int> &ivec,int ,vector<int>::size_type size);
    void merge(vector<int>&ivec,int p,int q,int r);
};

void Solution::merge_sort(vector<int> &ivec,int p ,vector<int>::size_type r)
{
    int q;
    if(p<r)
    {
        q = (p+r)/2;
        merge_sort(ivec,p,q);
        merge_sort(ivec,q+1,r);
        merge(ivec,p,q,r);
    }
}

void Solution::merge(vector<int>&ivec,int p,int q,int r)
{
    int i=0,j=0,k=p;
    vector<int>::iterator iter = ivec.begin();
    vector<int> lvec(iter+p,iter+q+1);
    vector<int> rvec(iter+q+1,iter+r+1);
    while(i<lvec.size()&&j<rvec.size())
    {
        if(lvec[i]<=rvec[j])
            ivec[k++]=lvec[i++];
        else
            ivec[k++]=rvec[j++];
    }
    if(i<lvec.size())
    {
        for(k;k<=r;k++,i++)
            ivec[k]=lvec[i];
    }
    else
    {
        for(k;k<=r;k++,j++)
            ivec[k]=rvec[j];
    }
}
时间: 2024-08-05 11:16:20

返回数组中元素之和为输入值的元素的下标(以1为基)的相关文章

【前端小小白的学习之路】----&gt;用JS编写一个函数,返回数组中重复出现过的元素

用JS编写一个函数,返回数组中重复出现过的元素,见下面的代码: var arr = [1, 2, 3, 1, 2, 3, 4, 5]; var getRepeat = function (arr) { var obj = {}; for (var i = 0, len = arr.length; i < len; i++) { if (obj[arr[i]] == undefined) { obj[arr[i]] = 1; } else { obj[arr[i]]++; } } for (var

编程之美 - 写一个函数,返回数组中所有元素被第一个元素除的结果

问题: 写一个函数,返回数组中所有元素被第一个元素除的结果,包含第一个元素,也要自己除自己 分析: 主要注意两点:1,判断输入是否合法:2,判断除数是否为0:3,从后往前除(真猥琐) 代码实现: 1 /* div_array.cc 2 * 2014/09/03 create 3 * 写一个函数,返回数组中所有元素被第一个元素除的结果,包含第一个元素,也要自己除自己 4 */ 5 #include <iostream> 6 using namespace std; 7 8 void div_ar

Leetcode题目215.数组中的第K个最大元素(中等)

题目描述: 在未排序的数组中找到第 k 个最大的元素.请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 示例 1: 输入: [3,2,1,5,6,4] 和 k = 2 输出: 5 示例 2: 输入: [3,2,3,1,2,4,5,5,6] 和 k = 4 输出: 4 说明: 你可以假设 k 总是有效的,且 1 ≤ k ≤ 数组的长度. 思路分析: 思路一:排序+遍历,如果是升序,那就是返回nums[n-k],如果是降序,那就是返回nums[k-1] class

LeetCode | 0215. Kth Largest Element in an Array数组中的第K个最大元素【Python】

LeetCode 0215. Kth Largest Element in an Array数组中的第K个最大元素[Medium][Python][快排][堆] Problem LeetCode Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element. Example 1:

LeetCode 10.移除数组中与给定值相同的元素

题目描述 给定一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,返回移除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成. 元素的顺序可以改变.你不需要考虑数组中超出新长度后面的元素. 示例 1: 给定 nums = [3,2,2,3], val = 3, 函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2. 你不需要考虑数组中超出新长度后面的元素. 示例 2: 给定 nums = [0,1

算法题:找出一个数组中依次最大的k个元素

package arithmetic; import java.util.Arrays; /** * 找出一个数组中依次最大的k个元素 * @author SHI */ public class FindMaxFigure { public static void main(String[] args) { int[] a=new int[]{1,5,-1,8,0,2}; System.out.println(Arrays.toString(findBigFigure(a, 3))); } /*

给定一整型数组,若数组中某个下标值大的元素值小于某个下标值比它小的元素值,称这是一个反序

[问题] 找出反序的个数 给定一整型数组,若数组中某个下标值大的元素值小于某个下标值比它小的元素值,称这是一个反序. 即:数组a[]; 对于i < j 且 a[i] > a[j],则称这是一个反序. 给定一个数组,要求写一个函数,计算出这个数组里所有反序的个数. [代码] #include <stdio.h> #include <stdlib.h> #include <string.h> int sumNum = 0; void merge(int *a,

返回数组中指定的一列

提取二维数组相同的键和键对应的值组成一个新的一维数组, tp不支持此函数,所以自己在php中找到,写在了tp的function下//array_column — 返回数组中指定的一列 function arrayColumn(array $array, $column_key, $index_key=null){ //本函数用来检查指定的函数是否已经定义.参数 function_name 为待检查的函数名称.若已定义指定的函数则返回 true 值,其它情形均返回 false 值. if(func

寻找数组中的第K大的元素,多种解法以及分析

遇到了一个很简单而有意思的问题,可以看出不同的算法策略对这个问题求解的优化过程.问题:寻找数组中的第K大的元素. 最简单的想法是直接进行排序,算法复杂度是O(N*logN).这么做很明显比较低效率,因为不要求别的信息只要计算出第K大的元素.当然,如果在某种情况下需要频繁访问第K大的元素就可以先进行一次排序在直接得出结果. 第一种方式是这样,用选择排序,冒泡法,或者交换排序这类的排序,对前K个元素进行排序.这三种算法也许不是最快的排序算法.但是都有个性质:计算出最大(小)的元素的算法复杂度是O(N