LeetCode题库

手动置顶

Posted by zhaiyunfan on April 17, 2021

1. 两数之和

题面

1. 两数之和

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

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。

示例:

给定 nums = [2, 7, 11, 15], target = 9

因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]

题解

暴力法

直接顺序双循环查找,O(n^2)

class Solution
{
public:
    vector<int> twoSum(vector<int>& nums, int target)
    {
        vector<int> result;
        for(int i=0;i<nums.size()-1;++i)
        {
            for(int j=i+1;j<nums.size();++j)
            {
                if(nums[i]+nums[j]==target)
                {
                    result.push_back(i);
                    result.push_back(j);
                    return result;
                }
            }
        }
        return result;
    }
};

哈希表

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        map<int,int> a;
        vector<int> b(2,-1);//结果
        for(int i=0;i<nums.size();i++)
        {
            if(a.count(target-nums[i])>0)
            {
                b[0]=a[target-nums[i]];
                b[1]=i;
                break;
            }
            a[nums[i]]=i;//如果不存在与之匹配的数,则将其放入map中,用来获取结果下标
        }
        return b;
    };
};

41. 缺失的第一个整数

题面

41. 缺失的第一个正数

给你一个未排序的整数数组,请你找出其中没有出现的最小的正整数。

示例 1:

输入: [1,2,0]
输出: 3
示例 2:

输入: [3,4,-1,1]
输出: 2
示例 3:

输入: [7,8,9,11,12]
输出: 1

提示:

你的算法的时间复杂度应为O(n),并且只能使用常数级别的额外空间。

题解

如果可以使用线性级别的额外空间:

建立以键为索引的伪hash表,由于一共有n个数,据鸽笼原理,第一个缺失的正整数必然在1到n+1之间

使用双数组构成hash表,值数组初始化为全0

插入过程为T(n)

按键遍历hash表的值数组,如果键是1到n的整数,则修改值为1,遍历过程为T(n)

遍历值数组的第1到n个值,如果哪个值为0,则对应的键为第一个未出现,输出并返回,如果遍历完成后为全1,则由鸽笼原理,n+1为第一个未出现,输出并返回,解决过程为T(n)

//有一说一,这都从LeetCode上荡的题,各种方法都做过了
#include<iostream>
#include<string.h>
#include<string>
#include<vector>
#include<map>
#include<math.h>
//#include <algorithm>

using std::cin;
using std::cout;
using std::endl;
using std::vector;
using std::string;
using std::map;
using std::pair;

//int Key[1000000];
int Value[1000000] = { 0 };


int main()
{
	vector<int> Key;
	
	int n;
	int temp;
	cin >> n;
	for (int i = 0; i < n; i++)
	{
		cin >> temp;
		//Key[i] = temp;
		Key.push_back(temp);
	}
	for (int i = 0; i < n; i++)
	{
		if (Key[i] > 0 && Key[i] <= n)
		{
			Value[Key[i]] = 1;
		}
	}
	for (int i = 1; i <= n; i++)
	{
		if (Value[i] == 0)
		{
			cout << i;
			return 0;
		}
	}
	cout << n + 1;
	return 0;
}

复杂度分析

O=T(N)+T(N)+T(N)=T(3N)

O(3N)->O(N)

空间复杂度为常数级(较大常数)

也可以优化为in place算法,遍历操作时进行前n个正整数向正确索引的换位即可,此时不需额外空间,线性空间占用

LCP 1. 猜数字

题面

LCP 1. 猜数字

小A 和 小B 在玩猜数字。小B 每次从 1, 2, 3 中随机选择一个,小A 每次也从 1, 2, 3 中选择一个猜。他们一共进行三次这个游戏,请返回 小A 猜对了几次?

输入的guess数组为 小A 每次的猜测,answer数组为 小B 每次的选择。guess和answer的长度都等于3。

示例 1:

输入:guess = [1,2,3], answer = [1,2,3]
输出:3
解释:小A 每次都猜对了。
示例 2:

输入:guess = [2,2,3], answer = [3,2,1]
输出:1
解释:小A 只猜对了第二次。
限制
1. guess的长度 = 3
2. answer的长度 = 3
3. guess的元素取值为 {1, 2, 3} 之一。
4. answer的元素取值为 {1, 2, 3} 之一。

我的题解

给新入门的小学生做的难度,bool运算可以取巧,没什么可说的

class Solution
{
public:
    int game(vector<int>& guess, vector<int>& answer)
    {
        return ((guess[0]==answer[0])+(guess[1]==answer[1])+(guess[2]==answer[2]));
    }
};