算法练习一

算法分析与设计 练习一

内容一

分别针对随机生成的若干组整数序列进行排序,排序算法使用四种方法。

1.InsertSort

源码:

#include <iostream>
#include <vector>
#include <cstdlib>
#include <ctime>

using namespace std;

//插入排序
void InsertSort(vector<int>& nums)
{
    int size = nums.size();

    //依次将nums[1]-nums[n-1]插入前面已排序序列,初始默认nums[0]有序
    for (int i = 1;i < size;i++)
    {
        //如果nums[i]小于前驱,需将nums[i]插入前面已排序序列
        if (nums[i] < nums[i - 1])
        {
            int temp = nums[i];

            int j;
            for (j = i - 1;j >= 0 && temp < nums[j];j--)
            {
                nums[j + 1] = nums[j];
            }

            nums[j + 1] = temp;
        }
    }
}

int main()
{
    //创建一个包含1000个范围在1-1000随机整数的数组
    vector<int> nums1(1000);
    srand(time(0));
    for (int i = 0;i < 1000;i++)
    {
        nums1[i] = 1 + rand() % 1000;

    }

    //插入排序
    clock_t start1 = clock();
    InsertSort(nums1);
    clock_t finish1 = clock();

    double duration1 = static_cast<double>(finish1 - start1);
    cout << "1000个随机数的运行时间为: " << duration1 << "毫秒" << endl;

    //创建一个包含10000个范围在1-10000随机整数的数组
    vector<int> nums2(10000);
    srand(time(0));
    for (int i = 0;i < 10000;i++)
    {
        nums2[i] = 1 + rand() % 10000;

    }

    //插入排序
    clock_t start2 = clock();
    InsertSort(nums2);
    clock_t finish2 = clock();

    double duration2 = static_cast<double>(finish2 - start2);
    cout << "10000个随机数的运行时间为: " << duration2 << "毫秒" << endl;

    //创建一个包含100000个范围在1-100000随机整数的数组
    vector<int> nums3(100000);
    srand(time(0));
    for (int i = 0;i < 100000;i++)
    {
        nums3[i] = 1 + rand() % 100000;

    }

    //插入排序
    clock_t start3 = clock();
    InsertSort(nums3);
    clock_t finish3 = clock();

    double duration3 = static_cast<double>(finish3 - start3);
    cout << "100000个随机数的运行时间为: " << duration3 << "毫秒" << endl;

    return 0;
}

时间复杂度:

最好情况下的时间复杂度为:O(N)

平均情况下的时间复杂度为:O(N^2)

最坏情况下的时间复杂度为:O(N^2)

空间复杂度: O(1)

稳定性:稳定

2.BubbleSort

源码:

#include <iostream>
#include <vector>
#include <cstdlib>
#include <ctime>

using namespace std;

//双向冒泡排序
void BubbleSort(vector<int>& nums)
{
    int low = 0, high = nums.size()-1;

    //一趟冒泡后记录元素是否交换标志,如果一趟冒泡后为false则说明未发生交换,即已有序
    bool flag = true;

    while(low <= high && flag)
    {
        flag = false;

        //从前向后冒泡,每趟把最大的元素放在最后面
        for (int i = low;i < high;i++)
        {
            if (nums[i] > nums[i + 1])
            {
                int temp1 = nums[i];
                nums[i] = nums[i + 1];
                nums[i + 1] = temp1;

                flag = true;
            }
        }

        high--;

        //从后往前冒泡,每趟把最小的元素放在最前面
        for(int i = high;i > low;i--)
        {
            if(nums[i] < nums[i-1])
            {
                int temp2 = nums[i];
                nums[i] = nums[i - 1];
                nums[i - 1] = temp2;

                flag = true;
            }
        }

        low++;
    }
}

int main()
{
    //创建一个包含1000个范围在1-1000随机整数的数组
    vector<int> nums1(1000);
    srand(time(0));
    for (int i = 0;i < 1000;i++)
    {
        nums1[i] = 1 + rand() % 1000;

    }

    //冒泡排序
    clock_t start1 = clock();
    BubbleSort(nums1);
    clock_t finish1 = clock();

    double duration1 = static_cast<double>(finish1 - start1);
    cout << "1000个随机数的运行时间为: " << duration1 << "毫秒" << endl;

    //创建一个包含10000个范围在1-10000随机整数的数组
    vector<int> nums2(10000);
    srand(time(0));
    for (int i = 0;i < 10000;i++)
    {
        nums2[i] = 1 + rand() % 10000;

    }

    //冒泡排序
    clock_t start2 = clock();
    BubbleSort(nums2);
    clock_t finish2 = clock();

    double duration2 = static_cast<double>(finish2 - start2);
    cout << "10000个随机数的运行时间为: " << duration2 << "毫秒" << endl;

    //创建一个包含100000个范围在1-100000随机整数的数组
    vector<int> nums3(100000);
    srand(time(0));
    for (int i = 0;i < 100000;i++)
    {
        nums3[i] = 1 + rand() % 100000;

    }

    //冒泡排序
    clock_t start3 = clock();
    BubbleSort(nums3);
    clock_t finish3 = clock();

    double duration3 = static_cast<double>(finish3 - start3);
    cout << "100000个随机数的运行时间为: " << duration3 << "毫秒" << endl;

    return 0;
}

时间复杂度:

最好情况下的时间复杂度为:O(N)

平均情况下的时间复杂度为:O(N^2)

最坏情况下的时间复杂度为:O(N^2)

空间复杂度: O(1)

稳定性:稳定

3.QuickSort

源码:

#include <iostream>
#include <vector>
#include <cstdlib>
#include <ctime>

using namespace std;

//划分算法,即一趟排序过程
int Partition(vector<int>& nums, int low, int high)
{
    //将数组中的第一个元素作为枢纽值,对数组进行划分
    int pivot = nums[low];

    while (low < high)
    {
        //比枢纽值小的元素移动到枢纽值的左端
        while (low < high && nums[high] >= pivot) high--;
        nums[low] = nums[high];

        //比枢纽值大的元素移动到枢纽值的右端
        while (low <high && nums[low] <= pivot) low++;
        nums[high] = nums[low];
    }

    //枢纽值存放在最终位置
    nums[low] = pivot;

    //返回存放枢纽值的最终位置
    return low;
}

void QuickSort(vector<int>& nums, int low, int high)
{
    if (low < high)
    {
        //划分
        int pivotpos = Partition(nums, low, high);

        //左半部分
        QuickSort(nums, low, pivotpos-1);

        //右半部分
        QuickSort(nums, pivotpos+1, high);

    }
}

int main()
{
    //创建一个包含1000个范围在1-1000随机整数的数组
    vector<int> nums1(1000);
    srand(time(0));
    for (int i = 0;i < 1000;i++)
    {
        nums1[i] = 1 + rand() % 1000;

    }

    //快速排序
    clock_t start1 = clock();
    QuickSort(nums1, 0, 999);
    clock_t finish1 = clock();

    double duration1 = static_cast<double>(finish1 - start1);
    cout << "1000个随机数的运行时间为: " << duration1 << "毫秒" << endl;

    //创建一个包含10000个范围在1-10000随机整数的数组
    vector<int> nums2(10000);
    srand(time(0));
    for (int i = 0;i < 10000;i++)
    {
        nums2[i] = 1 + rand() % 10000;

    }

    //快速排序
    clock_t start2 = clock();
    QuickSort(nums2, 0, 9999);
    clock_t finish2 = clock();

    double duration2 = static_cast<double>(finish2 - start2);
    cout << "10000个随机数的运行时间为: " << duration2 << "毫秒" << endl;

    //创建一个包含100000个范围在1-100000随机整数的数组
    vector<int> nums3(100000);
    srand(time(0));
    for (int i = 0;i < 100000;i++)
    {
        nums3[i] = 1 + rand() % 100000;

    }

    //快速排序
    clock_t start3 = clock();
    QuickSort(nums3, 0, 99999);
    clock_t finish3 = clock();

    double duration3 = static_cast<double>(finish3 - start3);
    cout << "100000个随机数的运行时间为: " << duration3 << "毫秒" << endl;

    return 0;
}

时间复杂度:

最好情况下的时间复杂度为:O(NlogN)

平均情况下的时间复杂度为:O(NlogN)

最坏情况下的时间复杂度为:O(N^2)

空间复杂度: O(logN)

稳定性:不稳定

4.MergeSort

源码:

#include <iostream>
#include <vector>
#include <cstdlib>
#include <ctime>

using namespace std;

//数组nums的左右两段nums[low...mid]和nums[mid+1...high]各自有序,将他们合并成一个有序表
void Merge(vector<int>& nums, vector<int>& copyNums, int low, int mid, int high)
{
    int size = nums.size();

    //将nums数组中的元素都复制到copyNums中
    for (int i = 0;i < size;i++)
    {
        copyNums[i] = nums[i];
    }

    int i = low, j = mid + 1, k=i;
    while (i <= mid || j <=high)
    {
        //比较copyNums数组左右两段中的元素,将较小值放入nums数组中
        if (i <= mid && j<=high)
        {
            if (copyNums[i] <= copyNums[j])
            {
                nums[k++] = copyNums[i++];
            }

            else
            {
                nums[k++] = copyNums[j++];
            }

        }

        //将右半部分剩余的元素放入nums数组中
        else if (i > mid)
        {
            nums[k++] = copyNums[j++];
        }

        //将左半部分剩余的元素放入nums数组中
        else
        {
            nums[k++] =copyNums[i++];
        }
    }
}

void MergeSort(vector<int>& nums, vector<int>& copyNums, int low, int high)
{
    if (low < high)
    {
        //划分子序列
        int mid = low + (high - low) / 2;
        MergeSort(nums, copyNums, low, mid);
        MergeSort(nums, copyNums, mid+1, high);

        //归并
        Merge(nums, copyNums, low, mid ,high);
    }
}

int main()
{
    //创建一个包含1000个范围在1-1000随机整数的数组
    vector<int> nums1(1000);
    srand(time(0));
    for (int i = 0;i < 1000;i++)
    {
        nums1[i] = 1 + rand() % 1000;

    }

    //辅助数组copyNums1
    vector<int> copyNums1(1000);

    //归并排序
    clock_t start1 = clock();
    MergeSort(nums1, copyNums1, 0, 999);
    clock_t finish1 = clock();

    double duration1 = static_cast<double>(finish1 - start1);
    cout << "1000个随机数的运行时间为: " << duration1 << "毫秒" << endl;

    //创建一个包含10000个范围在1-10000随机整数的数组
    vector<int> nums2(10000);
    srand(time(0));
    for (int i = 0;i < 10000;i++)
    {
        nums2[i] = 1 + rand() % 10000;

    }

    //辅助数组copyNums2
    vector<int> copyNums2(10000);

    //归并排序
    clock_t start2 = clock();
    MergeSort(nums2, copyNums2, 0, 9999);
    clock_t finish2 = clock();

    double duration2 = static_cast<double>(finish2 - start2);
    cout << "10000个随机数的运行时间为: " << duration2 << "毫秒" << endl;

    //创建一个包含100000个范围在1-100000随机整数的数组
    vector<int> nums3(100000);
    srand(time(0));
    for (int i = 0;i < 100000;i++)
    {
        nums3[i] = 1 + rand() % 100000;

    }

    //辅助数组copyNums3
    vector<int> copyNums3(100000);

    //归并排序
    clock_t start3 = clock();
    MergeSort(nums3, copyNums3, 0, 99999);
    clock_t finish3 = clock();

    double duration3 = static_cast<double>(finish3 - start3);
    cout << "100000个随机数的运行时间为: " << duration3 << "毫秒" << endl;

    return 0;
}

时间复杂度:

最好情况下的时间复杂度为:O(NlogN)

平均情况下的时间复杂度为:O(NlogN)

最坏情况下的时间复杂度为:O(NlogN)

空间复杂度: O(N)

稳定性:稳定

5.快速排序一趟Partition过程

初始序列:46, 38, 19, 45, 55, 92, 24, 46, 90

选取第一个元素作为pivot, 即pivot = 46

Partition: 24, 38, 19, 45, 55, 92, 46, 46, 90

​ 24, 38, 19, 45, 46, 92, 55, 46, 90

结果: 24, 38, 19, 45, 46, 92, 55, 46, 90

内容二 众数问题

在一个包含n个元素的多重集合S中,每个元素在S中出现的次数称为该元素的重数,多重集合S中重数最大的元素称为众数。

现要求对随机生成的由n个自然数组成的多重集合S, 编程计算S的众数及其重数

1.Mode

源码:

#include <iostream>
#include <vector>
#include <cstdlib>
#include <ctime>
#include <unordered_map>

using namespace std;

//寻找众数及其重数
pair<int, int> findMode(vector<int>& nums)
{
    //m的键为数组元素,m的值为一个数据元素在数组中出现的频率
    unordered_map<int, int> m;

    for (int i = 0;i < nums.size();i++)
    {
        //统计元素频率
        m[nums[i]]++;
    }

    //将统计结果存放在数组vec中
    vector<pair<int, int>> vec(m.begin(), m.end());

    //将众数和重数存放在mode中
    pair<int, int> mode;

    //找出众数和重数
    int maxValue = vec[0].second;
    for (int i = 1;i < vec.size();i++)
    {
        if (vec[i].second > maxValue)
        {
            maxValue = vec[i].second;
            mode = vec[i];
        }
    }

    return mode;
}

int main()
{
    //创建一个包含10个范围在1-10随机整数的数组
    vector<int> nums(10);
    srand(time(0));
    for (int i = 0;i < 10;i++)
    {
        nums[i] = 1 + rand() % 10;

    }

    //打印数组
    for(int i = 0;i < 10;i++)
    {
        cout << nums[i] << " ";
    }
    cout << endl;

    cout << "众数: " << findMode(nums).first << " 重数: " << findMode(nums).second << endl;
    
    return 0;
}

思路:

算法使用一个unordered_map的数据结构, 其键(key)为数组元素, 其值(value)为一个数据元素在数组中出现的频率。 算法遍历一次数组, 统计各数据元素出现的频率, 然后将统计结果存放在数组vec中, 最后遍历数组vec, 找出众数和重数放在mode中并返回。

时间复杂度:O(N)

空间复杂度:O(N)

内容三 最近点对问题

最近点对问题描述:对平面上给定的N个点,给出所有点对的最短距离。即,输入是平面上的N个点,输出是N点中具有最短距离的两点。

要求随机生成N个点的平面坐标,应用穷举法编程计算出所有点对的最短距离

要求随机生成N个点的平面坐标,应用分治法编程计算出所有点对的最短距离

1.ClosestPoints

源码:

#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstdlib>
#include <ctime>

using namespace std;

//Point类
class Point
{
public:
    int x;
    int y;
};

//计算两点之间的距离
float distance(const Point& p1, const Point& p2)
{
    return sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y));
}


//穷举法
/*float closestPoints(Point points[], Point record[], int n)
{
    float minDist = 9999;

    for (int i = 0;i < n;i++)
    {

        for (int j = i +1;j < n;j++)
        {
            float dist = distance(points[i], points[j]);
            if (dist < minDist)
            {
                minDist = dist;
                record[0] = points[i];
                record[1] = points[j];
            }
        }
    }

    return minDist;
}*/

//按x值升序排序
bool cmpX(const Point& p1, const Point& p2)
{
    return p1.x < p2.x;
}

//按y值升序排序
bool cmpY(const Point& p1, const Point& p2)
{
    return p1.y < p2.y;
}

//分治法,
float closestPointsHelper(Point points[], Point record[], int left, int right)
{
    //f1记录左半边点的最近距离,f2记录右半边点的最近距离,f3记录横跨两边的点的最近距离
    float f1, f2, f3, f;

    //只有两个点的情况
    if (right - left == 1)
    {
        f = distance(points[left], points[right]);
        record[0] = points[left];
        record[1] = points[right];
        return f;
    }

    //只有三个点的情况
    if (right - left == 2)
    {
        f1 = distance(points[left], points[left + 1]);
        f2 = distance(points[left + 1], points[right]);
        f3 = distance(points[left], points[right]);

        if((f1 < f2) && (f1 < f3))
        {
            f = f1;
            record[0] = points[left];
            record[1] = points[left + 1];
        }
        else if (f2 < f3)
        {
            f = f2;
            record[0] = points[left + 1];
            record[1] = points[right];
        }
        else
        {
            f = f3;
            record[0] = points[left];
            record[1] = points[right];
        }
        return f;
    }

    //大于3个点的情况
    int mid = left + (right - left) / 2;

    //划分左半边
    f1 = closestPointsHelper(points, record, left, mid);

    //辅助数组temp1
    Point temp1[2];
    temp1[0] = record[0];
    temp1[1] = record[1];

    划分右半边
    f2 = closestPointsHelper(points, record, mid + 1, right);

    //辅助数组temp1
    Point temp2[2];
    temp2[0] = record[0];
    temp2[1] = record[1];

    //取左、右两边点的距离的较小值
    if (f1 < f2)
    {
        f = f1;
        record[0] = temp1[0];
        record[1] = temp1[1];
    }
    else
    {
        f = f2;
        record[0] = temp2[0];
        record[1] = temp2[1];
    }

    //辅助数组midPoints
    int index = 0;
    Point midPoints[right - left + 1];

    //以mid为中心,f为半径划分一个长带,最小点对还有可能存在于这个长带中
    for (int i = mid;(i >= left) && (points[mid].x - points[i].x < f);i--)
    {
        midPoints[index++] = points[i];
    }

    for (int i=mid + 1;(i <= right) && (points[i].x - points[mid].x <f);i++){
        midPoints[index++] = points[i];
    }

    //按y值升序排序
    sort(midPoints, midPoints + index, cmpY);

    //找出长带中可能存在的最小距离
    for (int i = 0;i < index;i++)
    {
        for (int j = i + 1;j < index;j++)
        {
            //如果两点y值相减大于f,则这两点不可能是最近点对
            if ((midPoints[j].y - midPoints[i].y) >= f)
            {
                break;
            }
            else{
                f3 = distance(midPoints[i], midPoints[j]);
                if (f3 < f)
                {
                    f = f3;
                    record[0] = midPoints[i];
                    record[1] = midPoints[j];
                }
            }

        }
    }

    return f;
}

float closestPoints(Point points[], Point record[])
{
    return closestPointsHelper(points, record, 0, 9);
}

int main()
{
    //随机生成10个点
    Point points[10];

    srand(time(0) + 1);
    for (int i = 0;i < 10;i++)
    {
        points[i].x = 1 + rand() % 20;
    }

    srand(time(0) + 2);
    for (int i = 0;i < 10;i++)
    {
        points[i].y = 1 + rand() % 20;
    }

    //打印点集
    cout << "点集: " << endl;
    for (int i = 0;i < 10;i++)
    {
        cout << "(" << points[i].x << "," << points[i].y << ")" << endl;
    }

    //按y值升序排序
    sort(points, points + 10, cmpX);

    //数组record记录最近点对
    Point record[2];

    //float minDistance = closestPoints(points, record, 10);
    float minDistance = closestPoints(points, record);

    cout << "最近点对是: " << "(" << record[0].x << "," << record[0].y << ")";
    cout << endl;
    cout << "            " << "(" << record[1].x << "," << record[1].y << ")";
    cout << endl;
    cout << "最近距离为: " << minDistance <<endl;

    return 0;
}

思路:

距离的计算公式为:

img

穷举法通过遍历所有点集,计算出每一个点对的距离,计算出最近的距离并输出。 其主要循环的步骤就是计算距离。

分治法首先考虑将最近对问题进行分治,设计其分治策略。将点集S分成两个子集S1和S2,根据 平衡子问题原则,每个子集中的点数大致都为n/2。这样分治后,最近点对将会出现三种情况:在S1中,在S2中或者最近 点对分别在集合S1和S2中。利用递归分析法分别计算前两种情况,第三种方法另外分析。求解出三类子情况后, 再合并三类情况,比较分析后输出三者中最小的距离。

img

时间复杂度:

穷举法的时间复杂度:O(N^2)

分治法的时间复杂度:O(NlogN)

空间复杂度:

穷举法的空间复杂度:O(1)

分治法的空间复杂度:O(N)

内容四 最大子序列和

随机给出一个整数序列,选出其中连续且非空的一段使得这段和最大。

1.MaxSubArray

源码:

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

//动态规划
/*int maxSubArray(vector<int>& nums)
{
    //数据长度
    int size = nums.size();

    //pre记录上一个最大子序列和f(i - 1)
    int pre = 0;

    //result记录最大子序列和
    int result = nums[0];
    for (int i = 0;i < size;i++)
    {
        //f(i) = max(f(i - 1) + nums[i], nums[i])
        pre = max(pre + nums[i], nums[i]);
        result = max(pre, result);
    }

    return result;
}*/

//分治法
//寻找横跨左、右两边的最大子序列和
int findMaxCrossingSubArray(vector<int>& nums, int left, int mid, int right)
{
    int leftSum = INT_MIN;
    int sum = 0;
    for (int i = mid;i >= left;i--)
    {
        sum = sum + nums[i];
        leftSum = max(sum, leftSum);
    }

    int rightSum = INT_MIN;
    sum = 0;
    for (int i = mid + 1;i <= right;i++)
    {
        sum = sum + nums[i];
        rightSum = max(sum, rightSum);
    }

    int maxCrossingSum = leftSum + rightSum;

    return maxCrossingSum;
}

int maxSubArrayHelper(vector<int>& nums, int left, int right)
{
    //数组中只有一个数据元素的情况
    if (left == right)
    {
        return nums[left];
    }

    //其他情况
    int mid = left + (right - left) / 2;

    //左半边的最大子序列和
    int leftSum = maxSubArrayHelper(nums, left, mid);

    //左半边的最大子序列和
    int rightSum = maxSubArrayHelper(nums, mid + 1, right);

    //横跨左、右两边的最大子序列和
    int maxCrossingSum = findMaxCrossingSubArray(nums, left, mid, right);

    //比较三者找到最大子序列和
    int result = max(leftSum, rightSum);
    result = max(result, maxCrossingSum);

    return result;
}

int maxSubArray(vector<int>& nums)
{
    //数组长度
    int size = nums.size();

    return maxSubArrayHelper(nums, 0, size - 1);
}



int main()
{
    vector<int> nums = {-2, 1, -3, 4, -1, 2, 1, -5, 4};

    for (int i = 0;i < nums.size();i++)
    {
        cout << nums[i] << " ";
    }
    cout << endl;

    cout << "数组的最大子序列和为: " << maxSubArray(nums) <<endl;

    return 0;
}

思路:

动态规划:用 f(i)代表以第i个数结尾的最大子序列和。

​ 动态规划转移方程为 f(i) = max(f(i - 1) + nums[i], nums[i])。

分治法:取数组中心点作为中心,最大子序列和可能在中心左边,也可能在中心右边,也可能横跨中心。利用递归分析法分别计算前两种情况,第三种方法另外分析。求解出三类子情况后, 再合并三类情况,比较分析后输出三者中最大值。

时间复杂度:

动态规划的时间复杂度:O(N)

分治法的时间复杂度:O(NlogN)

空间复杂度:

动态规划的空间复杂度:O(1)

分治法的空间复杂度:O(logN)

内容五

输入正整数𝑥, 𝑝(𝑥 ≤ 10^9, 𝑝 ≤ 10^18) ,要求输出x^p (10^9+7) 。

1.Mod

源码:

#include <iostream>

using namespace std;

unsigned long long pow(int x, int p)
{
    const unsigned long long M = 1000000007;

    unsigned long long result = 1;

    for (int i = 1;i <= p;i++)
    {
        //result永远不会超过1000000007
        result = (result * x) % M;
    }

    return result;
}

int main()
{
    cout << pow(3, 5) << endl;
    cout << pow(3, 10000) << endl;
    return 0;
}

内容六

给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。

1.TwoSum

源码:

#include <iostream>
#include <vector>
#include <unordered_map>
#include <cstdlib>
#include <ctime>

using namespace std;

vector<int> twoSum(vector<int>& nums, int S)
{
    //数据长度
    int size = nums.size();

    //m的键为数组元素,m的值为该数据元素的下标
    unordered_map<int, int> m;

    for (int i = 0;i < size;i++)
    {
        //首先查询哈希表中是否存在target,然后将nums[i]插入到哈希表中,
        int target = S - nums[i];
        if (m.count(target))
        {
            //数组中存在两个元素和为S
            return vector<int>{i, m[target]};
        }

        m[nums[i]] = i;
    }

    //数组中存在两个元素和为S
    return vector<int>{-1, -1};

}


int main()
{
    //创建一个包含5个范围在1-9随机整数的数组
    vector<int> nums(5);
    srand(time(0));
    for (int i = 0;i < 5;i++)
    {
        nums[i] = 1 + rand() % 9;

    }

    //打印数组
    for(int i = 0;i < 5;i++)
    {
        cout << nums[i] << " ";
    }
    cout << endl;

    vector<int> result = twoSum(nums, 7);

    cout << result[0] << " " << result[1] <<endl;

    return 0;
}

思路:

算法枚举数组中的每一个数 nums[i],寻找数组中是否存在S - nums[i]。算法创建一个哈希表,对于每一个 nums[i],我们首先查询哈希表中是否存在 S - nums[i],然后将nums[i]插入到哈希表中(可保证不会让nums[i]和自己匹配), 这一过程时间复杂度为O(1)。

时间复杂度:O(N)

空间复杂度:O(N)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值