最近想系统的刷一刷题,所以在此记录一下以便于自己巩固和复习。如有问题请指正。
字符串
反转字符串
class Solution {
public:
void reverseString(vector<char>& s) {
int len = s.size();
char temp;
for(int i=0; i<len/2; i++){
temp = s[i];
s[i] = s[len-i-1];
s[len-i-1] = temp;
}
}
};
双指针
class Solution {
public:
void reverseString(vector<char>& s) {
for(int l=0,r=s.size()-1;l<r;l++,r--)swap(s[l],s[r]);
}
};
字符串转换整数 (atoi)
class Solution {
public:
int myAtoi(string s) {
long long result = 0;
if(!s.size()) return 0;
bool sign = true;
int i = 0;
while (s[i] == ' '){
i++;}
if (s[i] == '-'){
sign = false;
i++;
}else if (s[i] == '+'){
//注意这里不能是if,考虑-+ +-的情况
i++;
}
if (s[i] == 0){
return 0;
}
while(i < s.size()){
if(s[i] < '0' or s[i] > '9'){
break;
}
result = result * 10 + (s[i] - '0');
if(result > INT_MAX){
return sign ? INT_MAX : -INT_MAX-1;
}
i++;
}
return sign ? result : -result;
}
};
最长公共前缀
横向扫描法
class Solution {
public:
string longestCommonPrefix(vector<string>& strs) {
if(!strs.size()){
return "";
}
string prefix = strs[0];
for (int i = 1; i < strs.size(); i++){
prefix = longestCommonPrefix(prefix, strs[i]);
if(!prefix.size()){
return "";
}
}
return prefix;
}
string longestCommonPrefix(const string& str1, const string& str2) {
int len = min(str1.size(), str2.size());
int i = 0;
while(i < len && str1[i] == str2[i]){
i++;
}
return str1.substr(0, i);
}
};
纵向扫描法
class Solution {
public:
string longestCommonPrefix(vector<string>& strs) {
if(strs.size() == 0){
return "";
}
bool same;
for (int i = 0; i < strs[0].size(); i++){
char c = strs[0][i];
same = true;
for (int j = 1; j < strs.size(); j++){
if (strs[j][i] != c || i == strs[j].size()){
//如果遇到不同的字符或某个字符串已经遍历结束
return strs[0].substr(0,i);
}
}
}
return strs[0];
}
};
无重复字符的最长子串
https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例:
输入: s = “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
下面解法还有点难理解
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int i=-1,result = 0;
vector<int> dict(128,-1);
for(int j=0;j<s.size();j++){
i=max(i,dict[s[j]]);
dict[s[j]]=j;
result=max(result,j-i);
}
return result;
}
};
数组
删除排序数组中的重复项
给定一个排序数组,你需要在 原地 删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。
给定 nums = [0,0,1,1,1,2,2,3,3,4],
函数应该返回新的长度 5, 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4。你不需要考虑数组中超出新长度后面的元素。
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
if (nums.size()<=1){
return nums.size();
}
int i=0;
for(int j=1;j<nums.size();j++){
if (nums[j]!=nums[i]){
//相当于i维持新数组下标,每遇到一个新元素, 就把其复制到新数组
nums[++i]=nums[j];
}
}
return i+1;
}
};
移除元素
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int i=0;
for(int j=0; j<nums.size(); j++){
if(nums[j]!=val){
nums[i++]=nums[j];
}
}
return i;
}
};
数组中重复的数字
class Solution {
public:
int findRepeatNumber(vector<int>& nums) {
if(nums.size()<=1){
return -1;
}
unordered_set<int> cache;
for(int i=0;i<nums.size();i++){
if(cache.count(nums[i])){
return nums[i];
}
cache.insert(nums[i]);
}
return -1;
}
};
合并两个有序数组
https://leetcode-cn.com/problems/merge-sorted-array/
给你两个有序整数数组 nums1 和 nums2,请你将 nums2 合并到 nums1 中,使 nums1 成为一个有序数组。
初始化 nums1 和 nums2 的元素数量分别为 m 和 n 。你可以假设 nums1 的空间大小等于 m + n,这样它就有足够的空间保存来自 nums2 的元素。
从后向前比较
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
int i = m-1, j = n-1;
while(i+j+1 >= 0) {
if(j < 0 || (i >= 0 && nums1[i] >= nums2[j])){
nums1[i+j+1] = nums1[i];
i--;
}else if(i < 0 || (j >= 0 && nums1[i] < nums2[j])){
nums1[i+j+1] = nums2[j];
j--;
}
}
}
};
先copy后sort
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
for (int i=m,j=0; i<m+n; i++,j++){
nums1[i] = nums2[j];
}
sort(nums1.begin(), nums1.end());
}
};
扑克牌中的顺子
https://leetcode-cn.com/problems/bu-ke-pai-zhong-de-shun-zi-lcof
从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的。2~10为数字本身,A为1,J为11,Q为12,K为13,而大、小王为 0 ,可以看成任意数字。A 不能视为 14。
示例 2:输入: [0,0,1,2,5]
输出: True
注意:[0,0,1,2,5] 相当于[1,2,3,4,5]
分析:可以先排序,计算joker数量, 如果除了jokder还有重复值,返回false, 最后判断除了jodker的 首尾元素之差是不是小于5
class Solution {
public:
bool isStraight(vector<int>& nums) {
sort(nums.begin(), nums.end());
int joker = 0;
for(int i=0;i<4;i++){
if(nums[i] == 0){
joker++;
}else if(nums[i] == nums[i+1]){
return false;
}
}
return nums[4] - nums[joker] < 5;
}
};
买卖股票的最佳时机
https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock/
该题并没要求找出何时买卖的时机,只求最大利润
所以只需每次迭代更新谷底和最大利润值
class Solution {
public:
int maxProfit(vector<int>& prices) {
if (prices.size() == 0){
return 0;
}
int lowPrice = prices[0];
int profit = 0;
for(int i=1; i< prices.size(); i++){
if(prices[i] < lowPrice){
lowPrice = prices[i];
}
profit = max(profit, prices[i] - lowPrice);
}
return profit;
}
};
链表
链表逆置
https://leetcode-cn.com/problems/reverse-linked-list/
反转一个单链表。
示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
就地逆置
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode * next;
ListNode * new_head = nullptr;
while(head){
next = head->next;
head->next = new_head;
new_head = head;
head = next;
}
return new_head;
}
};
递归
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if (head == NULL || head->next == NULL){
return head;
}
ListNode* new_head = reverseList(head->next);
head->next->next=head; //例: 1->2<-3<-4<-5
head->next = NULL;
return new_head;
}
};
环形链表 II
快慢指针法
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *detectCycle(ListNode *head