1.合并两个有序链表
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
if(l1==NULL && l2==NULL)
return NULL;
if(l1==NULL && l2!=NULL)
return l2;
if(l2==NULL && l1!=NULL)
return l1;
ListNode* result=new ListNode();
ListNode* p=result;
while(l1 && l2)
{
ListNode* node=new ListNode();
if(l2->val==l1->val)
{
node->val=l1->val;
p->next=node;
ListNode* node1=new ListNode();
node1->val=l2->val;
node->next=node1;
p=node1;
l1=l1->next;
l2=l2->next;
if(l1==NULL)
break;
if(l2==NULL)
break;
}
else if(l2->val>l1->val)
{
node->val=l1->val;
p->next=node;
p=node;
l1=l1->next;
if(l1==NULL)
break;
}
else
{
node->val=l2->val;
p->next=node;
p=node;
l2=l2->next;
if(l2==NULL)
break;
}
}
if(l1) p->next=l1;
if(l2) p->next=l2;
return result->next;
}
};
2.两两交换链表中的节点
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
if(head==NULL)
return NULL;
ListNode* result=NULL;
if(head->next==NULL)
return head;
if(head->next->next==NULL)
{
result=head->next;
head->next->next=head;
head->next=NULL;
return result;
}
ListNode* first1=new ListNode(0);
ListNode* first=first1;
first->next=head;
ListNode* node=head;
while(node->next)
{
if(node->next->next==NULL)
{
node->next->next=node;
first->next=node->next;
node->next=NULL;
break;
}
ListNode* second=node->next->next;
first->next=node->next;
first=node;
node->next->next=node;
node->next=second;
node=second;
}
return first1->next;
}
};
3.删除排序数组中的重复项
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
if(nums.empty())
return 0;
nums.erase(unique(nums.begin(),nums.end()),nums.end());
return nums.size();
}
};
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
if(nums.empty())
return 0;
int i=0;
for(int j=1;j<nums.size();j++)
{
if(nums[i]!=nums[j])
i++;
nums[i]=nums[j];
}
return i+1;
}
};
4. 实现 strStr()
class Solution {
public:
int strStr(string haystack, string needle) {
if (needle == "")
return 0;
if (haystack == "")
return -1;
int size1 = haystack.size();
int size2 = needle.size();
int t = 0;
int i = 0;
for (; i < size1; i++)
{
if (haystack[i] == needle[t])
{
int a = i;
if (t == size2-1 || i == size1-1)
break;
else if (haystack[i + 1] != needle[t + 1])
{
i = i - t;
t = 0;
continue;
}
else
t++;
}
}
if (t + 1 < size2)
return -1;
if (size2 == 1 && i == 0 && haystack[0] != needle[0])
return -1;
if (size2 == 1 && i == size1 && haystack[i] != needle[0])
return -1;
if (t + 1 <size2 )
return -1;
return i - t ;
}
};
5.给定两个整数,被除数 dividend 和除数 divisor。将两数相除,要求不使用乘法、除法和 mod 运算符
class Solution {
public:
int divide(int dividend, int divisor) {
if(divisor==0)
return INT_MAX;
if(dividend==0)
return 0;
if(dividend==INT_MIN && divisor==1)
return INT_MIN;
if(dividend==INT_MIN && divisor==-1)
return INT_MAX;
long a=abs(dividend);
long b=abs(divisor);
long result=0;
while(a>=b)
{
a=a-b;
result++;
}
if(dividend<0 && divisor>0)
return (0-result);
if(dividend>0 && divisor<0)
return (0-result);
if(dividend<0 && divisor<0)
return result;
return result;
}
};
6.下一个排列
STL algorithmi算法s_sorted和is_sorted_until
该函数是測试范围内的元素是否已经有序
is_sorted_until
返回第一个破坏序列有序的元素迭代器
如果使用iter_swap函数,那么就可以进行交换了,先看一下函数的参数:
iter_swap(a,b);//a为一个迭代器,b为另一个迭代器。
顾名思义,iter_swap的功能就是交换两个迭代器的元素。
lower_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于或等
于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址
begin,得到找到数字在数组中的下标。
upper_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于num
的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,
得到找到数字在数组中的下标。
reverse()会将区间[beg,end)内的元素全部逆序
组合数学中经常用到排列,这里介绍一个计算序列全排列的函数
:next_permutation(start,end),和prev_permutation(start,end)。这两个函数作用是一样的,区别就在于前者
求的是当前排列的下一个排列,后一个求的是当前排列的上一个排列
f1
class Solution {
public:
void nextPermutation(vector<int>& nums) {
next_permutation(nums.begin(), nums.end());
}
};
f2
class Solution {
public:
void nextPermutation(vector<int>& nums) {
auto i = is_sorted_until(nums.rbegin(), nums.rend());
if(i != nums.rend())
iter_swap(i, upper_bound(nums.rbegin(), i, *i));
reverse(nums.rbegin(), i);
}
};
。
7.在排序数组中查找元素的第一个和最后一个位置
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
vector<int> result={-1,-1};
if(nums.empty())
return result;
auto first=lower_bound(nums.begin(),nums.end(),target);
auto second=upper_bound(nums.begin(),nums.end(),target);
int a,b;
if(first!=nums.end())
{
if(*first==target)
a=first-nums.begin();
else
return result;
if(*(second-1)==target)
b=second-1-nums.begin();
result[0]=a;
result[1]=b;
}
return result;
}
};
8.组合总和
深度优先搜索算法(Depth First Search,简称DFS):一种用于遍历或搜索树或图的算法。 沿着树的深度遍历树的节点,尽可能深的搜索树的分支。当节点v的所在边都己被探寻过或者在搜寻时结点不满足条件,搜索将回溯到发现节点v的那条边的起始节点。整个进程反复进行直到所有节点都被访问为止。属于盲目搜索,最糟糕的情况算法时间复杂度为O(!n)。 回溯法(探索与回溯法)是一种选优搜索法,又称为试探法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。
class Solution {
private:
vector<vector<int>> result={};
vector<int> tem={};
public:
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
sort(candidates.begin(),candidates.end());
if(candidates.empty() || target<=0)
return result;
sum_aux(0,target,candidates,candidates.size());
return result;
}
void sum_aux(int index,int target,vector<int>& candidates,int size)
{
if(target==0)
{
result.push_back(tem);
return;
}
else
{
for(int i=index;i<size && target-candidates[i]>=0;i++)
{
tem.push_back(candidates[i]);
sum_aux(i,target-candidates[i],candidates,size);
tem.pop_back();
}
}
}
};
9.组合总和 II
class Solution {
private:
vector<vector<int>> result={};
vector<int> tem={};
public:
vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
sort(candidates.begin(),candidates.end());
if(candidates.empty() || target<=0)
return result;
sum_aux(0,target,candidates,candidates.size());
sort(result.begin(),result.end());
result.erase(unique(result.begin(),result.end()),result.end());
return result;
}
void sum_aux(int index,int target,vector<int>& candidates,int size)
{
if(target==0)
{
result.push_back(tem);
return;
}
else
{
for(int i=index;i<size && target-candidates[i]>=0;i++)
{
tem.push_back(candidates[i]);
sum_aux(i+1,target-candidates[i],candidates,size);
tem.pop_back();
}
}
}
};
10.旋转链表
class Solution {
public:
ListNode* rotateRight(ListNode* head, int k) {
ListNode* res=NULL;
if(head==NULL)
return res;
ListNode* first=head;
if(head->next==NULL)
return head;
ListNode* end=head;
ListNode* last;
int len=1;
while(end->next)
{
len++;
last=end;
end=end->next;
}
k=k%len;
while(k>0)
{
end->next=first;
last->next=NULL;
first=end;
end=last;
ListNode* tem=first;
while(tem->next)
{
last=tem;
tem=tem->next;
}
k--;
}
return first;
}
};
f2
class Solution {
public:
ListNode* rotateRight(ListNode* head, int k) {
if(head==0 || head->next==0) return head;
int len = 1;
ListNode *tail = head;
while(tail->next){}
++len;
tail = tail->next;
}
tail->next = head;
if(k%=len){
for(int i=0; i<len-k; ++i) tail = tail->next;
}
ListNode *res = tail->next;
tail->next = 0;
return res;
}
};