常见算法题浅析

121 阅读1分钟

这是我参与8月更文挑战的第2天,活动详情查看:8月更文挑战

【孩子们的游戏】 10个人围成一圈【序号为1-10】,从1开始报数,凡报数为3的则退出,输出最后一个小朋友的序号

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

int main()
{
    int n;
    cin >> n;
    vector<int> vt;
    for(int i=1;i<=n;i++)
        vt.push_back(i);
    int count=0;
    int index=-1;
    while(vt.size()>1)
    {
        int count=0;
        while(count<3)
        {
            count++;
            index++;
            if(index==vt.size())
               index=0;
        }
            auto it=vt.begin()+index;
               vt.erase(it);
               index--;
    }
    cout << vt[0]<< endl;
    return 0;

}

解题思路:该题为约瑟夫环典型例题。 将输入的人数存在向量vt中,程序的边界判断为vt中人数为大于1,用两个变量分别记录报数的多少以及一轮循环下来数组中元素执行的下标数。

程序核心思路:

从1开始报数报到3的人则退出,设变量count为三人一组的循环,index变量记录向量中剩余人数的下标索引,if循环判断当vt向量中剩余的人数与index变量标记一轮删除后所处的位置下标数,相同且vt向量的长度大于1的时候,则再次开始上述的循环,直到vt向量中剩余人数为1时,此时打印该数字。

【三数之和】     x+y+z=1,x,y,z在nums中查找,最后返回x,y,z组成的数组.

#include<iostream>
#include<map>
#include<string>
#include<vector>
#include<cstdio>
#include<set>
#include<algorithm>
using namespace std;

set<vector<int>> findNum(vector<int> arr,int k)

{
     sort(arr.begin(), arr.end());
       set<vector<int>> res;
       vector<int> tmp(3);
       int n = arr.size();
       for (int m = 0; m < n; m++)
       {
              int j = m + 1;
              int i = n - 1;
              while (j < i)
              {
                     int sum = arr[m] + arr[i] + arr[j];
                     if (sum < k)
                           j++;
                     else if (sum > k)
                           i--;
                     else
                     {
                           tmp[0] = arr[m];
                           tmp[1] = arr[j];
                           tmp[2] = arr[i];
                           res.insert(tmp);
                           j++;
                           i--;
                     }
              }
       }
       return res;
}

int main()
{
       vector<int> nums{ -1,0,2,2,2,-4,1,2 };
       set<vector<int>> res = findNum(nums, 1);
       for (auto k : res)
       {
              for (int i = 0; i < k.size(); i++)
                     cout << k[i] << " ";
              cout << endl;
       }
       system("pause");
       return 0;
}

解题思路:该题为典型的求和例题

首先将nums中的数进行排序,并初始化一个存放结果的数组,然后依次遍历数组,首先以第一个数为基准,然后从第二个数和最后一个数开始,然后判断以这三个数为索引相加的和如果大于k,则就将使用i--,使用小一点数,反之,当三数之和的结果小于k时,则j++,即使用大一点的数,如果相等,则将这三个数放到结果向量中存储,此时将继续移动索引值j与i,即在数组中继续寻找符合条件的值,因为数组还未遍历结束,当数组遍历结束即j小于i时,此时将m+1,重复上述操作,此种三数之和的编程方法是最直观的,但是所需要的时间复杂度也是最高的。