001:两数之和(找到数组中两个元素和为指定值)
题目链接
https://leetcode-cn.com/problems/two-sum/
题目描述:
题目中给出的数组是无序的,且重排耗时为O(nlogn),故考虑HashTable,即当nums[i]在HashTable中时(必然),如果在HashTable中能查找到target-nums[i],那么这一组数即为所求。题目只需求一组。
时间复杂度:
用map存储关键字,由于是二叉树存储结构,每次查找时间应为O(logn),时间复杂度为O(nlogn)但该算法的常数会小些
002:两数相加
题目链接:
Leetcode002
题目描述:
给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储一位 数字。
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例:
输入:(2 -> 4 -> 3) + (5 -> 6 ->4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807
解题思路:
从低位到高位逐个相加,用一个常数变量指示上一次加法的进位情况,需要注意的就是当两个数都没有下一位,他们的进位仍可能有下一位,需要在这种情况下对计算的数进行下一位的添1
代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
int myadd(int a1,int a2,int& adder)
{
int first=a1+a2+adder;
if(first>=10)
{
first=first%10;
adder=1;
}
else adder=0;
return first;
}
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
int adder=0;
int first=myadd(l1->val,l2->val,adder);
ListNode *temp=new ListNode(first);
ListNode* l3=temp;
while(l1->next!=NULL&&l2->next!=NULL)
{
l1=l1->next;l2=l2->next;
int myval=myadd(l1->val,l2->val,adder);
ListNode*p=new ListNode(myval);
l3->next=p;
l3=l3->next;
}
while(l1->next!=NULL)
{
l1=l1->next;
int myval=myadd(l1->val,0,adder);
ListNode*p=new ListNode(myval);
l3->next=p;
l3=l3->next;
}
while(l2->next!=NULL)
{
l2=l2->next;
int myval=myadd(0,l2->val,adder);
ListNode*p=new ListNode(myval);
l3->next=p;
l3=l3->next;
}
if(l1->next==NULL&&l2->next==NULL&&adder==1)
{
int myval=myadd(0,0,adder);
ListNode*p=new ListNode(myval);
l3->next=p;
l3=l3->next;
}
return temp;
}
};
015:三数之和
题目链接:
Leetcode015
题目描述:
给定一个包含 n 个整数的数组
nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c =
0 ?找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
例如, 给定数组 nums =
[-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]
题目思路:
这个题目是Leetcode001的升级版,但是最终思路还是相同的,将数组排成有序,再对于每一个数,对他后面的数查找是否有两个数的和为他的相反数。注意规避重复的数。
在优化算法方面,需要做到,当第一个数为正数时,就停止整个算法,直接返回所需的二维数组。
代码:
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
sort(nums.begin(),nums.end());
vector<vector<int>> a;
for(int i=0;i<nums.size()&&nums[i]<=0;i++)
if((i!=0&&nums[i]!=nums[i-1])||i==0)
{
int front=i+1,end=nums.size()-1;
if(front==end)
continue;
while(front<end)
{
if(nums[front]+nums[end]>-nums[i])
do {end--;}
while((nums[end]==nums[end+1])&&front<end);
else if(nums[front]+nums[end]<-nums[i])
do {front++;}
while((nums[front]==nums[front-1])&&front<end);
else
{
vector<int> aa;
aa.push_back(nums[i]);
aa.push_back(nums[front]);
aa.push_back(nums[end]);
a.push_back(aa);
do {front++;}
while((nums[front]==nums[front-1])&&front<end);
do {end--;}
while((nums[end]==nums[end+1])&&front<end);
}
}
}
return a;
}
};