LeetCode1-2
- 说明:笔记内容为刷LeetCode题目时所记录,其中题目与示例均为网站上原文,分析及代码为个人的一些见解以及知识点的备份,刷题过程中有时会参考一些优秀算法,若有涉及到侵权或者其他不当行为请联系我删除致歉,若有兴趣交流指点或者相互学习也可以发送邮件联系,不胜感激。
- 邮件地址:qiao_jinming@foxmail.com
- 题目网站:LeetCode
1、两数之和
-
题目:给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
-
关键字:暴力;哈希
-
示例:给定 nums = [2, 7, 11, 15], target = 9,因为 nums[0] + nums[1] = 2 + 7 = 9,所以返回 [0, 1]。
-
分析:题目看起来是典型的暴力算法题,因为结果只有一组,数据不能重复使用,可以定义两个循环,先用第一个数据遍历整个容器,再用第二个数据遍历…最终返回整个下标对,循环遍历需要n*(n-1)/2次,即复杂度为O(n2)。
-
代码:
class Solution_violet{
public:
vector<int> twoSum(vector<int>& nums,int target){
int i,j,flag=0;
vector<int> res;
for(i=0;i<nums.size();i++){
for(j=i+1;j<nums.size();j++){
if(nums[i]+nums[j]==target){
res.push_back(i);
res.push_back(j);
flag = 1;
break;
}
}
if(flag == 1)break;
}
return res;
}
};
-
知识点:map内部实现红黑树,unordered_map内部实现哈希表,对于红黑树(平衡二叉搜索树)而言遍历后的map键值对是有序的,哈希表是通过关键字来进行位置访问,查找复杂度为O(1)。map具有有序性,但占用较大空间;unordered_map查找速度非常快,但是建立比较耗费时间。分别需要引入头文件map与unordered_map,map可以进行的操作为:
- 插入: map.insert((1,“string”));
- 大小: map.size();
- 判断: map.count(1);//判断关键字是否出现,是则返回1
- 查找: map.find(1);map.begin();map.end();//返回关键字对应值,首元素与尾元素
- 删除: map.erase(map.find(1));
- 判断空值: map.empty();
- 全部删除: map.clear();
- max_size();//返回可容纳的最大元素个数
- rbegin();rend()//返回逆向迭代器
-
再分析:map可以以常数的时间查找结果,本题需要在容器中寻找符合条件的两个值,所以在寻找第二个值(target-sums[first]),直接判断此值是否在容器中即可,这样复杂度可缩小为O(n)。
-
代码:
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, int> map;
vector<int> res;
for (int i = 0; i < nums.size(); ++i) {
map[nums[i]] = i;
}
for (int i = 0; i<nums.size(); i++) {
int t = target - nums[i];
if (map.count(t) && map[t] != i) {
res.push_back(i);
res.push_back(map[t]);
break;
}
}
return res;
}
};
2、两数相加
-
题目:给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
-
关键字:链表
-
示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807 -
分析:基本的链表操作,因为是逆序,所以第一位加出来是个位,以此类推。这里需要处理的是进位问题,初始化链表头val为0,*next为NULL,当l1与l2非空时,把对应位的数字相加,并将对10取模的数字存入temp,累加数除10,此时保留的即为进位数,在进行累加,当l1或者l2为空时,sum累加的仅为非空的链表,当全部加完,若sum不为零,说明还有最后的进位1,放置在temp的末尾即可,返回第一个指针,注意头指针初始化为0。链表操作可以突破机器的数字位限制。
-
代码:
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode* result = new ListNode(0);
ListNode* temp = result;
int sum = 0;
while(l1 || l2){
if(l1){
sum += l1->val;
l1 = l1->next;
}
if(l2){
sum += l2->val;
l2 = l2->next;
}
temp -> next = new ListNode(sum%10);
sum /= 10;
temp = temp -> next;
}
if(sum)temp -> next =new ListNode(1);
return result->next;
}
};