C++复习(二十二)——LeetCode1-2

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;
		    }
	};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值