LeetCode Day 1
1.TwoSum
- 给定一个整数数组nums和一个目标值 target,请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下标。
- 你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
- 示例:给定 nums = [2, 7, 11, 15], target = 9,因为 nums[0] + nums[1] = 2 + 7 = 9
- 所以返回:[0, 1]。
- 遍历一次源数组nums,对于其中每一个变量nums[i],计算其与target的差值diff;
- 在临时数组values中查找是否之前有任意一个nums[i]与diff一样;
- 如果有,则找到那是第几个元素,与当前i一同输出;
- 如果没有,则将当前值存入临时数组values;
/**
* @param {number[]} nums
* @param {number} target
* @return {number[]}
*/
var twoSum = function(nums, target) {
let values = [];
for (let i = 0, len = nums.length; i < len; i++) {
let diff = target - nums[i];
if (values.includes(diff)) {
return [values.indexOf(diff), i]
}
values.push(nums[i]);
}
};
2.AddTwoNumbers
- 给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
- 您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
- 示例:
- 输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
- 输出:7 -> 0 -> 8
- 原因:342 + 465 = 807
- 考虑进位。
- 考虑最后一位计算完毕正好为10的时候需要新加下一位。
- 考虑l1和l2位数不等的情况。
var addTwoNumbers = function(l1, l2) {
let rootNode = new ListNode();
let parentNode = rootNode;
let carry = false;
while (true) {
let curDigit = (l1 ? l1.val : 0) + (l2 ? l2.val : 0) + (carry ? 1 : 0);
let remainder = curDigit - 10;
parentNode.val = (remainder < 0 ? curDigit : remainder);
carry = (remainder >= 0);
l1 = l1 ? l1.next : l1;
l2 = l2 ? l2.next : l2;
if (l1 || l2) {
parentNode.next = new ListNode();
parentNode = parentNode.next;
}
else {
if (carry) {
parentNode.next = new ListNode();
parentNode.next.val = 1;
}
else {
parentNode = null;
}
break;
}
}
return rootNode;
};
4.FindMedianSortedArrays
- 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。
- 请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。
- 你可以假设 nums1 和 nums2 不会同时为空。
- 时间复杂度若为O(m+n)的话,先确定nums1和nums2是增序还是倒序;
- 增序的让指针指向头从头到尾读数据,倒序的话让指针指向末尾,从后往前读;
- 比较当前读到的两个数值,总是优先将小的那个压入临时数组temp;
- 判断temp个数是奇数还是偶数,返回相应的中位数即可。
//这里我们默认俩数组都是增序,我们先按这个思路提交一下看看是否Accept,测试一下leetcode
var findMedianSortedArrays = function (nums1, nums2) {
//题目设定nums1和nums2不会同时为空
if (nums1) {
if (nums2) {
let i = 0, j = 0, lens1 = nums1.length, lens2 = nums2.length;
let tmp = [];
while (i < lens1 && j < lens2) {
if (nums1[i] < nums2[j]) {
tmp.push(nums1[i]);
i++;
}
else {
tmp.push(nums2[j])
j++;
}
}
if (i < lens1) {
tmp = tmp.concat(nums1.slice(i));
}
if (j < lens2) {
tmp = tmp.concat(nums2.slice(j));
}
let totalLen = lens1 + lens2;
if (totalLen % 2 === 0) {
return (tmp[totalLen / 2 - 1] + tmp[totalLen / 2]) / 2;
}
else {
return tmp[Number.parseInt(totalLen / 2)];
}
}
else {
let lens1 = nums1.length;
if (lens1 % 2 === 0) {
return (nums1[lens1 / 2 - 1] + nums1[lens1 / 2]) / 2;
}
else {
return nums1[Number.parseInt(lens1 / 2)];
}
}
}
else {
let lens2 = nums2.length;
if (lens2 % 2 === 0) {
return (nums2[lens2 / 2 - 1] + nums2[lens2 / 2]) / 2;
}
else {
return nums2[Number.parseInt(lens2 / 2)];
}
}
};
- 想让时间复杂度为logn,我们一般考虑二分算法。
- 求中位数,其实就是求第k小的数的一种特殊情况,假设我们要找第k小的数,我们可以每次循环排除掉k/2个数。比较两个数组的第k/2个数字,如果k是奇数,向下取整。
- 两个有序数组的中位数即为:1、两个数组长度(m+n)为奇数,求第(m+n+1)/2小元素;2、两个数组长度(m+n)为偶数,求第(m+n)/2小、第(m+n)/2+1小数字两者的平均值。
- 规律:A[1] ,A[2] ,A[3],A[k/2] ... ,B[1],B[2],B[3],B[k/2] ... ,如果 A[k/2]<B[k/2] ,那么A[1],A[2],A[3],A[k/2]都不可能是第k小的数字。
- 这是因为,在A 数组中,比 A[k/2] 小的数有k/2-1个,而对于B数组而言,已知A[k/2]小于B[k/2],就算除了B[k/2],它前边的数字都比 A[k/2] 小,也只有k/2-1个数,所以比 A[k/2] 小的数字最多有 k/2-1+k/2-1=k-2个,所以 A[k/2] 最多是第 k-1 小的数。而比 A[k/2] 小的数更不可能是第k小的数了,所以可以A[1],A[2]...A[k/2]都排除掉。
- 我们每次都是取k/2的数进行比较,有时候可能会遇到数组长度小于k/2的时候,此时将箭头指向数组末尾就可以了。采用递归的思路,每次比较min(k/2,len(数组)) 对应的数字,把小的那个对应的数组的数字排除,将两个新数组进入递归,并且k要减去排除的数字的个数。递归终止的条件为k=1或者某一个数组为空,此时找非空数组的第k个值即可。
/**
* @param {number[]} nums1
* @param {number[]} nums2
* @return {number}
*/
var findMedianSortedArrays = function (nums1, nums2) {
// 题目设定nums1和nums2不会同时为空
let totalLen = (nums1 ? nums1.length : 0) + (nums2 ? nums2.length : 0);
if (totalLen % 2 === 0) {
// 偶数则要返回第K个和第K+1个
// 因为我在函数里使用的是shift和splice操作,会影响源数组
// 所以找出第K个之后,两个数组中最小k个数就已经都被排除掉了
// 想找俩数组中第k+1个,只要在后续的俩数组中找第一个最小数即可
return (findKthNumberArrays(nums1, nums2, totalLen / 2) + findKthNumberArrays(nums1, nums2, 1)) / 2;
}
else {
//奇数直接返回第K个即可
return findKthNumberArrays(nums1, nums2, (totalLen + 1) / 2);
}
};
function findKthNumberArrays(nums1, nums2, k) {
if (k === 1) {
//不可能存在两者都为空的情况
if (nums1 && nums1.length > 0) {
if (nums2 && nums2.length > 0) {
//弹出两者小的那一个,大的那一个要留着以便二次比较
if (nums1[0] > nums2[0]) {
return nums2.shift();
} else {
return nums1.shift();
}
}
else {//nums1不为空,num2为空
return nums1.shift();
}
} else {//nums1为空,nums2不空
return nums2.shift();
}
}
else {
//不可能存在两者都为空的情况
if (nums1 && nums1.length > 0) {
if (nums2 && nums2.length > 0) {
let interval = Math.floor(k / 2);
// 小的那个数组移除掉k/2个数
// 再找新数组中第k-interval小的数即可
// 要注意K/2可能会比数组本身长度大的多,因此数组不一定取得到k/2-1的值,此时取数组最大值即可
let digit1 = interval > nums1.length ? nums1[nums1.length - 1] : nums1[interval - 1];
let digit2 = interval > nums2.length ? nums2[nums2.length - 1] : nums2[interval - 1];
if (digit1 > digit2) {
interval = Math.min(nums2.length, interval);
nums2.splice(0, interval);
return findKthNumberArrays(nums1, nums2, k - interval);
}
else {
interval = Math.min(nums1.length, interval);
nums1.splice(0, interval);
return findKthNumberArrays(nums1, nums2, k - interval);
}
}
else {//nums2为空,返回nums1中第k个即可,因为是有序数组,第k小也就是第k个数前面k个小数要排除掉以便后续操作
let tmp = nums1.splice(0, k);
return tmp[k - 1];
}
}
else {//nums1为空,循环结束,返回num2中第k个即可,与上面nums1一样的操作
let tmp = nums2.splice(0, k);
return tmp[k - 1];
}
}
}
LeetCode Day 1的更多相关文章
- 我为什么要写LeetCode的博客?
# 增强学习成果 有一个研究成果,在学习中传授他人知识和讨论是最高效的做法,而看书则是最低效的做法(具体研究成果没找到地址).我写LeetCode博客主要目的是增强学习成果.当然,我也想出名,然而不知 ...
- LeetCode All in One 题目讲解汇总(持续更新中...)
终于将LeetCode的免费题刷完了,真是漫长的第一遍啊,估计很多题都忘的差不多了,这次开个题目汇总贴,并附上每道题目的解题连接,方便之后查阅吧~ 477 Total Hamming Distance ...
- [LeetCode] Longest Substring with At Least K Repeating Characters 至少有K个重复字符的最长子字符串
Find the length of the longest substring T of a given string (consists of lowercase letters only) su ...
- Leetcode 笔记 113 - Path Sum II
题目链接:Path Sum II | LeetCode OJ Given a binary tree and a sum, find all root-to-leaf paths where each ...
- Leetcode 笔记 112 - Path Sum
题目链接:Path Sum | LeetCode OJ Given a binary tree and a sum, determine if the tree has a root-to-leaf ...
- Leetcode 笔记 110 - Balanced Binary Tree
题目链接:Balanced Binary Tree | LeetCode OJ Given a binary tree, determine if it is height-balanced. For ...
- Leetcode 笔记 100 - Same Tree
题目链接:Same Tree | LeetCode OJ Given two binary trees, write a function to check if they are equal or ...
- Leetcode 笔记 99 - Recover Binary Search Tree
题目链接:Recover Binary Search Tree | LeetCode OJ Two elements of a binary search tree (BST) are swapped ...
- Leetcode 笔记 98 - Validate Binary Search Tree
题目链接:Validate Binary Search Tree | LeetCode OJ Given a binary tree, determine if it is a valid binar ...
- Leetcode 笔记 101 - Symmetric Tree
题目链接:Symmetric Tree | LeetCode OJ Given a binary tree, check whether it is a mirror of itself (ie, s ...
随机推荐
- Python笔记_第一篇_面向过程_第一部分_0.开场白
*什么是Python? Python是一种面向对象的解释型计算机程序设计语言,由荷兰人Guido(吉多) van Rossum于1989年发明,第一个公开版本发行于1991年.在国外应用非常的广泛,国 ...
- Spring Bean的生命周期、Spring MVC的工作流程、IOC,AOP
1.Spring Bean的生命周期? (1)构造方法实例化bean. (2)构造方法设置对象属性. (3)是否实现aware接口,三种接口(BeanNameAware,BeanFactoryAwar ...
- error_reporting() 设置 PHP 的报错级别并返回当前级别
error_reporting() 设置 PHP 的报错级别并返回当前级别. 语法 error_reporting(report_level) 如果参数 level 未指定,当前报错级别将被返回.下面 ...
- MobX 在 hook 中的使用
关于 mobX 在 react 16.8.0 以上的用法 以下例子均取自官网文档 一般用法: import { observer, useLocalStore } from 'mobx-react'; ...
- Gradle project sync failed. Please fix your project and try again
https://stackoverflow.com/questions/29808199/error-running-android-gradle-project-sync-failed-please ...
- PAT Advanced 1084 Broken Keyboard (20) [Hash散列]
题目 On a broken keyboard, some of the keys are worn out. So when you type some sentences, the charact ...
- The mplot3d Toolkit
简介 正如,pyplot模块被用来绘制二维图,matplotlib使用mplot3d模块绘制三维图形,在mplot3d模块中存在 mpl_toolkits.mplot3d.axes3dmpl_tool ...
- 分布式场景下Kafka消息顺序性的思考
如果业务中,对于kafka发送消息异步消费的场景,在业务上需要实现在消费时实现顺序消费, 利用kafka在partition内消息有序的特点,消息消费时的有序性. 1.在发送消息时,通过指定parti ...
- git 推送到github最常用命令
初始化仓库,上传到github中. git init git add README.md git commit -m "first commit" git remote add o ...
- Tooltips2
#include<windows.h> #include<Commctrl.h> #include"resource.h" #pragma comment( ...