前言
本人刷leetcode接近1年,大概做了200多题,大多数是简单以及中等难度,苦于编程水平无太大进展,大多数简单题目还是有思路,可难度稍微上升一些或是涉及到技巧性的题目便很难一时有解法。于是决定借鉴一下他人总结的leetcode解题集,在阅读他人解法以及代码基础上进行总结,根据他的思路在leetcode上自己手写一遍代码并在博客对其中提到的方法加以总结,总结如下。参考来源:https://github.com/soulmachine/leetcode
目录
1.删除排序数组中的重复项 II(中等)
2.搜索旋转排序数组(中等)
3.最长连续序列(困难)
4.两数之和(简单)
5.三数之和(中等)
6.最接近的三数之和(中等)
7.四数之和(中等)
8.下一个排列(中等)
一 数组
1.删除排序数组中的重复项 II(中等)
题目描述:
给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素最多出现两次,返回移除后数组的新长度。
不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。
样例输入输出:
给定 nums = [1,1,1,2,2,3],
函数应返回新长度 length = 5, 并且原数组的前五个元素被修改为 1,1,2,2,3。
你不需要考虑数组中超出新长度后面的元素。
解法详解:
代码:
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
if (nums.size() <= 2) return nums.size();
int index = 2;
for (int i = 2; i < nums.size(); i++){
if (nums[i] != nums[index - 2])
nums[index++] = nums[i];
}
return index;
}
};
思路:
用变量index记录下一个非重复数(重复次数不超过2的数)应该放的下标,由于前两个数肯定要放在数组里(不管重复还是不重复,所以从第3个数循环遍历数组,判断这个数是否与下标【index - 2】的数相等,如果相等,说明这个数也与下标【index - 1】的数相等,这个已经出现第3次,不考虑放入数组中;否则放入数组对应index位置,并且index++;这个思路是由之前删除排序数组中的重复项I中的解法拓展而来,思路类似,在I中不允许数组中出现重复元素,所以每次比较对象是【index - 1】。
代码:
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
const int n = nums.size();
int index = 0;
for (int i = 0; i < n; ++i) {
if (i > 0 && i < n - 1 && nums[i] == nums[i - 1] && nums[i] == nums[i + 1])
continue;
nums[index++] = nums[i];
}
return index;
}
};
思路:换个思路,由于数组是已经排序好的,如果出现一串重复序列,我们只取该序列的第一个与最后一个元素即可,因此循环遍历数组,对于其中的每个数,如果是数组的头与尾,则直接加入数组中,同理还是用index下标进行记录;如果不是的话,只要判断该数是不是重复序列的头与尾,即判断nums[i] == nums[i - 1] && nums[i] == nums[i + 1]是否成立,如果不成立,则加入数组。
2.搜索旋转排序数组(中等)
题目描述:
假设按照升序排序的数组在预先未知的某个点上进行了旋转。
( 例如,数组 [0,1,2,4,5,6,7]
可能变为 [4,5,6,7,0,1,2]
)。
搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回 -1
。
你可以假设数组中不存在重复的元素。
你的算法时间复杂度必须是 O(log n) 级别。
样例输入输出:
输入: nums = [4,5,6,7,0,1,2], target = 0
输出: 4
解法详解:
代码:
class Solution {
public:
int search(vector<in