leetcode解题记录(1)
简单记录leetcode刷题过程。
1、两数之和
**题目描述:**给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。你可以按任意顺序返回答案。
C++暴力解法:
class Solution{
public:
vector<int> twoSum(vector<int>& nums,int target){
int i=0,j=0;
int size=nums.size();
for(i=0;i<size-1;i++){
for(j=i+1;j<size;j++){
if(nums[i]+nums[j]==target){ //若存在两数满足条件
return {i,j}; //返回数组下标
break;
}
}
}
return{i,j};
}
};
暴力解法的思路比较简单,基本就是在数组中用两层循环寻找符合条件的答案;
时间复杂度:O(N^2);空间复杂度:O(1);
两遍Hash方法:
Hash表的方法就是将元素一一对应,就是建立一个映射关系;C++代码如下:
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
map<int,int> a;//建立hash表存放数组元素
vector<int> b(2,-1);//存放结果
for(int i=0;i<nums.size();i++)
a.insert(map<int,int>::value_type(nums[i],i)); //按一定格式存入map
for(int i=0;i<nums.size();i++)
{
if(a.count(target-nums[i])>0&&(a[target-nums[i]]!=i))
//count==1表示找到和为target的两个元素;判断是否找到目标元素且目标元素不能是本身
{
b[0]=i;
b[1]=a[target-nums[i]];
break;
}
}
return b;
};
};
因为map中有函数count,可以直接找到合适的元素,故不用再用依次循环搜索;
map容器的使用:🔗:https://www.cnblogs.com/yonglin1998/p/11780828.html
示例代码如下:
#include<map>
#include<string>
#include<iostream>
using namespace std;
int main() {
map<int, string> mapStudent;//creat a map,its element consists an int and an string
mapStudent.insert(pair<int, string>(1, "student_one"));//map's insert operation
mapStudent.insert(pair<int, string>(3, "student_two"));
mapStudent.insert(pair<int, string>(4, "student_three"));
map<int, string>::iterator iter;//creat a map pointer to point a element in a map
for (iter = mapStudent.begin(); iter != mapStudent.end(); iter++) {
cout << iter->first << " " << iter->second << endl;//output operation
}
}
运行结果如下:
一般称map的第一个元素为关键字(int型),第二个元素为对应关键字的值(string或者int型)
一边插入一遍搜索的方法:
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
map<int,int> hash;
vector<int> b;//存放结果
hash.insert(map<int,int>::value_type(nums[0],0));//将第一个元素插入hash
for(int i=1;i<nums.size();i++){
hash.insert(map<int,int>::value_type(nums[i],i));
if((hash.count(target-nums[i])>0)&&(hash[target-nums[i]]!=i)){
b.push_back(hash[target-nums[i]]);
b.push_back(i);
return b;
}
}
return b;
};
};
26、删除排序数组中的重复项
题目描述给定一个排序数组,你需要在 原地 删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。
不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
我的方法由于是sorted array,所以是比较简单的,我的方法是遍历array中的每一个元素,当这个元素和其前一个元素的值不相等时,返回的cnt就++,然后修改原array对应位置的value即可,c++代码如下:
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
if(nums.size()==0){
return 0;
}
int cnt=1;
for(int i=1;i<nums.size();i++){
if(nums[i]!=nums[i-1]){
cnt++;
nums[cnt-1]=nums[i];
}
}
return cnt;
};
};
双指针解法
设置快慢指针,快指针和慢指针指向内容不同时,就可以改变数组中内容了:
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
if (nums.empty())
return 0; // 数组为空的判断
int slow = 0,fast=0; //快慢指针
for ( fast = 0; fast < (nums.size() - 1); fast++){
if(nums[fast] != nums[fast + 1]) { // 发现和后一个不相同
nums[++slow] = nums[fast + 1]; //slow = 0 的数据一定是不重复的,所以直接 ++slow
}
}
return slow + 1; //slow是从0开始的,所以返回slow + 1
}
};
C语言版:
int removeDuplicates(int* nums, int numsSize){
if(numsSize==0){
return 0;
}
int cnt=1; //用于记录非重复元素数目
int *fast;int*slow; //快慢指针
slow=nums; //慢指针直接指向数组首元素
fast=slow+1; //快指针指向第2个元素
for(;fast<(nums+numsSize);fast++){
if(*fast!=*slow){ //快慢指针指向内容
cnt++;
nums[cnt-1]=*fast;
slow=fast;
}
}
return cnt;
}
只要记住双指针这个思路就好!
移除元素
题目描述
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
我的解法:
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
if(nums.size()==0){
return 0;
}
int cnt;
for(int i=0;i<nums.size();i++){
if(nums[i]!=val){ //若不等于val
cnt++; //计数增加
nums[cnt-1]=nums[i];//改变数组的值
}
}
return cnt;
};
};
双指针的解法
思路是让一个快指针在前面探路寻找值不等于val的位置,然后复制后放到慢指针的位置。
C++解法:
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
if(nums.empty()){return 0;}
int slow=0, fast=0;//快慢指针定义
int cnt=0; //用于计数
for(fast=0;fast<=nums.size()-1;fast++){
if(nums[fast]!=val){//不等于时,需要的操作是赋值,计数,slow移动
cnt++;
nums[slow]=nums[fast];
slow++;
}
if(nums[fast]==val){//等于时不需要任何操作,继续移动fast即可
}
}
return cnt;
}
};
35、搜索插入位置
**题目描述:**给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
你可以假设数组中无重复元素。
暴力解法:
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
if(target<nums[0]){
return 0;
}
for(int i=0;i<nums.size();i++){
if(i!=nums.size()-1){if((target>nums[i])&&(target<nums[i+1])){
return i+1;
}}
if(target==nums[i]){
return i;
}
}
return nums.size();
};
};