LeetCode C++刷题 1-4题题解

1、两数之和

题目:

给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。

示例:

给定 nums = [2, 7, 11, 15], target = 9

因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/two-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题解:

主要用了三种解法:

1、暴力法

2、双指针法

3、hash法

代码:

class Solution {
public:
	vector<int> twoSum(vector<int>& nums, int target){
		//方法一:暴力法
		/*vector<int> result;
		for (int i = 0; i < nums.size(); i++)
		{
			for (int j = i + 1; j < nums.size(); j++)
			{
				if (nums[i] + nums[j] == target) {
					result.push_back(i);
					result.push_back(j);
					return result;
				}
			}
		}
		return result;*/
		
		//方法二:双指针法
		// vector<int> result;
		// vector<int> nums2;
		// nums2 = nums;
		// sort(nums.begin(), nums.end());
		// int i = 0;
		// int j = nums.size() - 1;

		// while (i < j) {
		// 	if (nums[i] + nums[j] < target) {
		// 		i++;
		// 	}
		// 	else if (nums[i] + nums[j] > target)
		// 	{
		// 		j--;
		// 	}
		// 	else {
		// 		break;
		// 	}
		// }

		// for (int p = 0; p < nums2.size();p++) {
		// 	if (nums2[p] == nums[i] || nums2[p] == nums[j]) {
		// 		result.push_back(p);
		// 		if (result.size() == 2) {
		// 			return result;
		// 		}
		// 	}
		// }

        //hash法
		vector<int> result;
		unordered_map<int,int> hash;
		for (int i = 0; i < nums.size(); i++)
		{
			if (hash[target - nums[i]] &&
				hash[target - nums[i]] != i + 1)
			{
				result.push_back(hash[target - nums[i]] - 1);
                result.push_back(i);
				return result;
			}
			hash[nums[i]] = i + 1;
		}

		return result;
	}
};

2、两数相加

题目:

给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。

如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。

您可以假设除了数字 0 之外,这两个数都不会以 0 开头。

示例:

输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/add-two-numbers
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题解:

链表逐位相加,并通过变量记录进位。

代码:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        ListNode* result = nullptr;
		if (!l1 && !l2) {
			return result;
		}
		if (l1 && !l2) {
			return l1;
		}
		if (!l1 && l2) {
			return l2;
		}
        int sum = l1->val + l2->val;
        int y = (l1->val + l2->val) % 10;
        int c = (l1->val + l2->val) / 10;
		result = new ListNode(y);
		ListNode* copy = result;
		l1 = l1->next;
        l2 = l2->next;
		while (l1) {
			int val = l1->val;
			if (l2) {
				val += l2->val;
				l2 = l2->next;
			}
            y = (val + c) % 10;
            c = (val + c) / 10;
			ListNode *node = new ListNode(y);
			copy->next = node;
			copy = copy->next;
			l1 = l1->next;
		}
		while (l2) {
			int val = l2->val;
            y = (val + c) % 10;
            c = (val + c) / 10;			
			ListNode *node = new ListNode(y);
			copy->next = node;
            copy = copy->next;
			l2 = l2->next;
		}
        if(c){
            ListNode* node = new ListNode(c);
            copy->next = node;
        }
		return result;
    }
};

3、无重复字符的最大长串

题目:

给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。

示例 1:

输入: "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:

输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:

输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
     请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题解:

滑动窗口

代码:

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        //滑动窗口
		unordered_set<char> window;
		int max_length = 0;
		int left = 0;
		for (int i = 0;i < s.size(); i++)
		{
			while (window.find(s[i]) != window.end()) {
				window.erase(s[left]);
				left++;
			}
            window.insert(s[i]);
			max_length = max(max_length, i - left + 1);
		}
		return max_length;
    }
};

4、寻找两个正序数组的中位数

题目:

给定两个大小为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。

请你找出这两个正序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。

你可以假设 nums1 和 nums2 不会同时为空。

 

示例 1:

nums1 = [1, 3]
nums2 = [2]

则中位数是 2.0
示例 2:

nums1 = [1, 2]
nums2 = [3, 4]

则中位数是 (2 + 3)/2 = 2.5

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题解:

1、暴力法

2、二分法

代码:

#include<iostream>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;
class Solution
{
public:
	double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2)
	{
		//1暴力法
		/*vector<int> num;
		int i = 0;
		int j = 0;
		while (i < nums1.size() || j < nums2.size()) {
			if (i < nums1.size() && j < nums2.size()) {
				if (nums1[i] < nums2[j]) {
					num.push_back(nums1[i]);
					i++;
				}
				else if (nums1[i] > nums2[j])
				{
					num.push_back(nums2[j]);
					j++;
				}
				else {
					num.push_back(nums1[i]);
					i++;
					num.push_back(nums2[j]);
					j++;
				}
			}
			else {
				if (i < nums1.size()) {
					num.push_back(nums1[i]);
					i++;
				}
				if (j < nums2.size()) {
					num.push_back(nums2[j]);
					j++;
				}
			}
			
		}
		if (num.size() % 2 == 0) {
			return (num[num.size() / 2] + num[num.size() / 2 + 1]) / 2;
		}
		else {
			return num[(num.size() + 1) / 2];
		}*/

		//2 二分法
		if (nums1.size() > nums2.size())
		{
			vector<int> temp = nums1;
			nums1 = nums2;
			nums2 = temp;
		}

		int m = nums1.size();
		int n = nums2.size();

		int total = (m + n + 1) / 2;

		int left = 0;
		int right = m;

		while (left < right) {
			int i = left + (right - left + 1) / 2;
			int j = total - i;

			if (nums1[i - 1] > nums2[j])
			{
				right = i - 1;
			}
			else {
				left = i;
			}
		}

		int i = left;
		int j = total - i;

		int FIRST_LEFT = i == 0 ? INT_MIN : nums1[i - 1];
		int FIRST_RIGHT = i == m ? INT_MAX : nums1[i];
		int SECOND_LEFT = j == 0 ? INT_MIN : nums2[j - 1];
		int SECOND_RIGHT = j == n ? INT_MAX : nums2[j];

		if ((m + n) % 2 == 0) {
			return (((double)max(FIRST_LEFT, SECOND_LEFT) + (double)min(FIRST_RIGHT, SECOND_RIGHT))/2);
		}
		else {
			return max(FIRST_LEFT, SECOND_LEFT);
		}

	}
};

 

©️2020 CSDN 皮肤主题: 数字20 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值