算法第一周LeetCode解题报告

1. Two Sum

问题描述:

Given an array of integers, return indices of the two numbers such that they add up to a specific target.

You may assume that each input would have exactly one solution, and you may not use the same element twice.

样例:

Given nums = [2, 7, 11, 15], target = 9,

Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].

解题思路:

    考虑到输入样例中的数组中应该没有非常大的数字,我决定使用哈希的方法来加速计算。首先创立了两个数组a[100000]和b[100000]作为哈希的容器,每个数的哈希值就是其本身,a用于存储正数和0,b用于存储负数。因此构造的哈希容器允许样例的输入值的范围是[-100000 ~ 99999];另外,为了解决数组中有某个元素重复出现的问题,我还设置了othera[100000]和otherb[100000]用于重复出现的元素的标识。

     程序首先遍历一遍数组,设元素e,索引值为index,若e >= 0,则a[e]=index;若e<0则b[e]=index;同时,如果该元素对应的哈希容器中已经存放索引,则othera[e] = 1(e >=0,否则otherb[e] = 1);

     然后,再次遍历数组,设 diff = target - e; 若diff == e 则查看对应的other容器中的标识位是否有索引,否则,查看对应的a和b容器中是否有索引。这里需要注意的是a和b容器中存放的总是某个元素在数组中最后一次出现的位置。

代码如下:

class Solution {
public:
	vector<int> twoSum(vector<int>& nums, int target) {
		vector<int> a(100000);
		vector<int> b(100000);
		vector<bool> othera(100000);
		vector<bool> otherb(100000);
		for (int i = 0; i < nums.size(); i++){
			if (nums[i] >= 0){
				if (a[nums[i]] != 0) othera[nums[i]] = true;
				a[nums[i]] = i + 1;
			}
			else {
				if (b[-nums[i]] != 0) otherb[-nums[i]] = true;
				b[-nums[i]] = i + 1;
			}
		}
		for (int i = 0; i < nums.size(); ++i){
			int diff = target - nums[i];
			if (diff == nums[i]){
				if (diff >= 0 && othera[nums[i]] == false) continue;
				if (diff < 0 && otherb[nums[i]] == false) continue;
			}
			if (diff >= 0 && a[diff] != 0) {
				


程序的运行结果如下:


    

2.Add Two Numbers

问题描述:

You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.

You may assume the two numbers do not contain any leading zero, except the number 0 itself.

样例:
Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8
解题思路:
    这一题考验的是简单的链表遍历操作,因此没什么好说的,需要注意的是当其中一个链表已经便利完,而进位又为0的时候,可以直接将长的链表的剩余部分直接链接到结果链表上以加速计算。

代码如下:
class Solution {
public:
	ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
		int l1B = 0;
		int l2B = 0;
		ListNode* res(NULL);
		ListNode* cur(NULL), *next(NULL);
		int carry = 0;
					if (res == NULL){
				res = new ListNode(0);
				cur = next = res;
			}
		while (l1 != NULL && l2 != NULL){

			next = new ListNode(0);
			next->val = l1->val + l2->val + carry;
			carry = next->val / 10;
			next->val %= 10;
			cur->next = next;
			cur = next;
			l1 = l1->next;
			l2 = l2->next;
		}
		while (l1 != NULL){
		 	if (carry == 0){
				cur->next = l1;
				break;
			}
			next = new ListNode(0);
			next->val = l1->val  + carry;
			carry = next->val / 10;
			next->val %= 10;
			cur->next = next;
			cur = next;
			l1 = l1->next;
		}
		while (l2 != NULL){
		    	if (carry == 0){
				cur->next = l2;
				break;
			}
			next = new ListNode(0);
			next->val = l2->val + carry;
			carry = next->val / 10;
			next->val %= 10;
			cur->next = next;
			cur = next;
			l2 = l2->next;
		}
		if (carry != 0){
			next = new ListNode(carry);
			cur->next = next;
		}
		return res -> next;
	}
};

程序运行结果如下:


3. Longest Substring Without Repeating Characters
问题描述:
Given a string, find the length of the longest substring without repeating characters.
输入样例:

Given "abcabcbb", the answer is "abc", which the length is 3.

Given "bbbbb", the answer is "b", with the length of 1.

Given "pwwkew", the answer is "wke", with the length of 3. Note that the answer must be a substring"pwke" is a subsequence and not a substring.

解题思路:
    这道题的加速思路一共有三:第一,使用哈希表hash[]记录当前考虑的子串中每个字母出现的索引位置,若没有出现则为-1;第二,使用了一个由start 和 end标记的变长滑块,每当end的端出现了重复字母e,先将记录当先start的值OG,然后将原字符串start 到 hash[e]中的字符对应的哈希表位置置为-1,然后另start = OG, 则完成了滑块的平移操作。最后,返回滑块的总长度;第三点是一个小技巧,就是当前剩余的可变长度明显小于已经记录的滑块最大长度,则直接返回当前滑块最大长度

代码如下:
class Solution {
public:
	int lengthOfLongestSubstring(string s) {
		int max = 0;
		if (s.empty()) return 0;
		int hash[300] = {0};
		int start, end;
		start = end = 0;
		for (int i = 0; i < s.length(); ++i){
			if (s.length() - start <= max) return max;
			end = i;
			if (hash[s[i]] == 0){
				hash[s[i]] = i + 1;
			}
			else{
				max = max >= end - start ? max : end - start;
				int tmp = hash[s[i]];
				for (int j = start; j <= hash[s[i]] - 1; ++j){
					hash[s[j]] = 0;
				}
				hash[s[i]] = i + 1;
				start = tmp;
			}
		}
		max = max >= end + 1 - start ? max : end + 1 - start;
		return max;
	}
};

运行结果如下:


4. Median of Two Sorted Arrays
问题描述

There are two sorted arrays nums1 and nums2 of size m and n respectively.

Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).

输入样例

Example 1:

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

The median is 2.0

Example 2:

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

The median is (2 + 3)/2 = 2.5

解题思路:
    这一题其实十分简单,考虑两个有序数组如何合并成一个有序数组即可,事实上我们只需要考虑两个数组当前最小的数如何放置的问题即可。这一题的难点要处理一些边界条件比较繁琐。

代码如下:
class Solution {
public:
	double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
		if (nums2.size() == 0){
			double pos = (nums1.size() - 1) / 2.0;
			if (pos != (int)(pos)){
				return (nums1[(int)pos] + nums1[(int)pos + 1]) / 2.0;
			}
			return nums1[(int)pos];
		}
		if (nums1.size() == 0){
			double pos = (nums2.size() - 1) / 2.0;
			if (pos != (int)(pos)){
				return (nums2[(int)pos] + nums2[(int)pos + 1]) / 2.0;
			}
			return nums2[(int)pos];
		}
		int total = (nums1.size() + nums2.size());
		int pos = (1 + total) / 2;
		bool isOdd = (1 + total) % 2 == 0 ? 1 : 0;
		int pa = 0;
		int pb = 0;
		double curVal = 0;
		if (isOdd){
			for (int i = 0; i < pos; ++i){
				if (pa >= nums1.size()){
					curVal = nums2[pb];
					++pb;
				}
				else if (pb >= nums2.size()){
					curVal = nums1[pa];
					++pa;
				}
				else if (nums1[pa] < nums2[pb]){
					curVal = nums1[pa];
					++pa;
				}
				else {
					curVal = nums2[pb];
					++pb;
				}
			}
			return curVal;
		}
		else {
			for (int i = 0; i < pos; ++i){
				if (pa >= nums1.size()){
					curVal = nums2[pb];
					++pb;
				}
				else if (pb >= nums2.size()){
					curVal = nums1[pa];
					++pa;
				}
				else if (nums1[pa] < nums2[pb]){
					curVal = nums1[pa];
					++pa;
				}
				else {
					curVal = nums2[pb];
					++pb;
				}
			}
			if (pa >= nums1.size()) return (nums2[pb] + curVal) / 2.0;
			else if (pb >= nums2.size()) return  (nums1[pa] + curVal) / 2.0;
			else return nums1[pa] < nums2[pb] ? (nums1[pa] + curVal) / 2.0 : (nums2[pb] + curVal) / 2.0;
		}
	}
};
运行结果如下:


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值