[LeetCode]
题目13 Roman to Integer
Input is guaranteed to be within the range from 1 to 3999.
思路
基本字符 | I | V | X | L | C | D | M |
对应阿拉伯数字 | 1 | 5 | 10 | 50 | 100 | 500 | 1000 |
- 相同的数字连写,所表示的数等于这些数字相加得到的数,例如:III = 3
- 小的数字在大的数字右边,所表示的数等于这些数字相加得到的数,例如:VIII = 8
- 小的数字,限于(I、X和C)在大的数字左边,所表示的数等于大数减去小数所得的数,例如:IV = 4
- 正常使用时,连续的数字重复不得超过三次
- 在一个数的上面画横线,表示这个数扩大1000倍(本题只考虑3999以内的数,所以用不到这条规则)
var romanToInt = function(s) { var array=[]; for(var i=0;i<s.length;i++){ var word=s.substring(i,i+1); switch (word){ case "I": array[i]=1; break; case "V": array[i]=5; break; case "X": array[i]=10; break; case "L": array[i]=50; break; case "C": array[i]=100; break; case "D": array[i]=500; break; case "M": array[i]=1000; break; } } var result=array[0]; for(var j=0;j<(array.length-1);j++){ if(array[j+1]>array[j]){ result+=(array[j+1]-array[j]*2) }else{ result+=array[j+1]; } } return result; };
题目 70. Climbing Stairs
You are climbing a stair case. It takes n steps to reach to the top.
Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?
Note: Given n will be a positive integer.
var climbStairs = function(n) { if(n<=2){ return n; }else{ var arr=[1,2]; for(var i=2;i<n;i++){ arr[i]=arr[i-1]+arr[i-2]; } return arr[n-1]; } };
解法二:
var climbStairs = function(n) { if (n == 0 || n == 1){ return 1; } var pre = 1; var current = 1; for (var i = 2; i <= n; i++) { var temp = current + pre; pre = current; current = temp; } return current; };
题目 136
Single Number
Given an array of integers, every element appears twice except for one. Find that single one.
Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?
[解题思路]
对于异或来说:
1. 异或运算是可交换,即 a ^ b = b ^ a
2. 0 ^ a = a
那么如果对所有元素做异或运算,其结果为那个出现一次的元素,理解是a1 ^ a2 ^ ....,可以将所有相同元素交换至相邻位置,首先运算相同元素,则会产生(n - 1)/2个0异或积,剩余一个单一元素,他们的异或积为这个单一元素自己,得解。
js代码:
var singleNumber = function(nums) { if(nums===null || nums.length===0){ return 0; } var result=nums[0]; for(var i=1;i<nums.length;i++){ result=result^nums[i]; } return result; };
本题扩展
1.一个数组中有两个元素只出现一次,其他所有元素都出现两次,求这两个只出现一次的元素
[解题思路]
将数组所有元素都进行异或得到一个不为0的结果,根据这个结果中的不为0的某一位将数组分成两组
将两组中的元素进行异或,如两个数组的异或值都不为0,则得到最后结果。
题目461 Hamming Distance汉明距离
The Hamming distance between two integers is the number of positions at which the corresponding bits are different.
Given two integers x
and y
, calculate the Hamming distance.
Note:
0 ≤ x
, y
< 231.
Example:
Input: x = 1, y = 4 Output: 2 Explanation: 1 (0 0 0 1) 4 (0 1 0 0) ↑ ↑ The above arrows point to positions where the corresponding bits are different.
解法1:
先求出两个数的异或值,遍历异或结果的每一位,统计为1的个数,即得出结果。
var hammingDistance = function(x, y) { var count=0; var result=x^y; result=result.toString(2); result=result.split(""); for(var i=0;i<result.length;i++){ if(result[i]=="1"){ count++; } } return count; };
var hammingDistance = function(x, y) { var count=0; var result=x^y; for(var i=0;i<32;i++){ if(result & (1<<i)){ count++; } } return count; };
解法2:
两个数字之间的汉明距离就是其二进制数对应位不同的个数,那么最直接了当的做法就是按位分别取出两个数对应位上的数并异或,我们知道异或的性质上相同的为0,不同的为1,我们只要把为1的情况累加起来就是汉明距离了,参见代码如下:
var hammingDistance = function(x, y) { var count=0; for(var i=0;i<32;i++){ if(( x & ( 1 << i ) ) ^ ( y & ( 1 << i ) )){ count++; } } return count; };
解法3:
假如数为num, num & (num - 1)可以快速地移除最右边的bit 1, 一直循环到num为0, 总的循环数就是num中bit 1的个数。参见代码如下:
var hammingDistance = function(x, y) { var count=0; var result=x^y; while (result) { ++count; result &= (result - 1); } return count; };
题目344 Reverse String
Write a function that takes a string as input and returns the string reversed.
Example:
Given s = "hello", return "olleh".
解法1:
将字符串转换成数组。然后for循环从数组末尾开始向前整合。
var reverseString = function(s) { var str=[]; var result=""; str=s.split(""); for(var i=str.length-1;i>=0;i--){ result+=str[i]; } return result; };
解法2:
通过递归的方式来做:
var reverseString = function(s) { var length=s.length; if(length<=1){ return s; } var strLeft=s.slice(0,Math.floor(length/2)); var strRight=s.slice(Math.floor(length/2),length); return reverseString(strRight)+reverseString(strLeft); };
题目121. Best time to Buy and Sell Stock
Description: Say you have an array for which the ith element is the price of a given stock on day i. If you were only permitted to complete at most one transaction (ie, buy one and sell one share of the stock), design an algorithm to find the maximum profit.
题意:用一个数组表示股票每天的价格,数组的第i个数表示股票在第i天的价格。 如果只允许进行一次交易,也就是说只允许买一支股票并卖掉,求最大的收益。
解法1:
分析:动态规划法。从前向后遍历数组,记录当前出现过的最低价格,作为买入价格,并计算以当天价格出售的收益,作为可能的最大收益,整个遍历过程中,出现过的最大收益就是所求。
代码:
var maxProfit = function(prices) { if(prices.length<2){ return 0; } var buy_price=prices[0]; var maxProfit=0; for(var i=1;i<prices.length;i++){ buy_price=Math.min(buy_price,prices[i-1]); maxProfit=Math.max(maxProfit,prices[i]-buy_price); } return maxProfit; };
解法2:
var maxProfit = function(prices) { if(prices.length<2){ return 0; } var maxCur=0; var maxSoFar=0; for(var i=1;i<prices.length;i++){ maxCur = Math.max(0, maxCur += prices[i] - prices[i-1]); maxSoFar = Math.max(maxCur, maxSoFar); } return maxSoFar; };
解法3:
只需要找出最大的差值即可,即 max(prices[j] – prices[i]) ,i < j。一次遍历即可,在遍历的时间用遍历low记录 prices[o....i] 中的最小值,就是当前为止的最低售价,时间复杂度为 O(n)。
var maxProfit = function(prices) { if(prices.length<2){ return 0; } var low=prices[0]; var ans=0; for(var i=1;i<prices.length;i++){ if(prices[i]<low){ low=prices[i]; }else if(prices[i]-low>ans){ ans=prices[i]-low; } } return ans; };
题目198.House Robber
You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security system connected and it will automatically contact the police if two adjacent houses were broken into on the same night.
Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police.
Credits:
Special thanks to @ifanchu for adding this problem and creating all test cases. Also thanks to @ts for adding additional test cases.
解法1:
var rob = function(nums) { var a = 0; var b = 0; for (var i=0; i<nums.length; i++) { if (i%2===0) { a = Math.max(a+nums[i], b); } else { b = Math.max(a, b+nums[i]); } } return Math.max(a, b); };
解法2:
这道题的本质相当于在一列数组中取出一个或多个不相邻数,使其和最大。那么我们对于这类求极值的问题首先考虑动态规划Dynamic Programming来解,我们维护一个一位数组dp,其中dp[i]表示到i位置时不相邻数能形成的最大和,那么递推公式怎么写呢,我们先拿一个简单的例子来分析一下,比如说nums为{3, 2, 1, 5},那么我们来看我们的dp数组应该是什么样的,首先dp[0]=3没啥疑问,再看dp[1]是多少呢,由于3比2大,所以我们抢第一个房子的3,当前房子的2不抢,所以dp[1]=3,那么再来看dp[2],由于不能抢相邻的,所以我们可以用再前面的一个的dp值加上当前的房间值,和当前房间的前面一个dp值比较,取较大值当做当前dp值,所以我们可以得到递推公式dp[i] = max(num[i] + dp[i - 2], dp[i - 1]), 由此看出我们需要初始化dp[0]和dp[1],其中dp[0]即为num[0],dp[1]此时应该为max(num[0], num[1]),代码如下:
var rob = function(nums) { if(nums.length===0){ return 0; } if(nums.length===1){ return nums[0]; } var d=[]; d[0]=nums[0]; d[1]=(nums[0]>nums[1]?nums[0]:nums[1]); for (var i=2; i<=nums.length; i++) { d[i]=Math.max(d[i-2]+nums[i],d[i-1]); } return d[nums.length-1]; };
题目396. Rotate Function
Given an array of integers A
and let n to be its length.
Assume Bk
to be an array obtained by rotating the array A
k positions clock-wise, we define a "rotation function" F
on A
as follow:
F(k) = 0 * Bk[0] + 1 * Bk[1] + ... + (n-1) * Bk[n-1]
.
Calculate the maximum value of F(0), F(1), ..., F(n-1)
.
Note:
n is guaranteed to be less than 105.
Example:
A = [4, 3, 2, 6]
F(0) = (0 * 4) + (1 * 3) + (2 * 2) + (3 * 6) = 0 + 3 + 4 + 18 = 25
F(1) = (0 * 6) + (1 * 4) + (2 * 3) + (3 * 2) = 0 + 4 + 6 + 6 = 16
F(2) = (0 * 2) + (1 * 6) + (2 * 4) + (3 * 3) = 0 + 6 + 8 + 9 = 23
F(3) = (0 * 3) + (1 * 2) + (2 * 6) + (3 * 4) = 0 + 2 + 12 + 12 = 26
So the maximum value of F(0), F(1), F(2), F(3) is F(3) = 26.
解法一:
分析:
F(k) = 0 * Bk[0] + 1 * Bk[1] + ... + (n-1) * Bk[n-1]
F(k-1) = 0 * Bk-1[0] + 1 * Bk-1[1] + ... + (n-1) * Bk-1[n-1] = 0 * Bk[1] + 1 * Bk[2] + ... + (n-2) * Bk[n-1] + (n-1) * Bk[0]
F(k) - F(k-1) = Bk[1] + Bk[2] + ... + Bk[n-1] + (1-n)Bk[0] = (Bk[0] + ... + Bk[n-1]) - nBk[0] = sum - nBk[0]
F(k) = F(k-1) + sum - nBk[0]
/** * @param {number[]} A * @return {number} */ var maxRotateFunction = function(A) { var f=0; var sum=0; var max; var length=A.length; for(var i=0;i<length;i++){ f+=i*A[i]; sum+=A[i]; } max=f; for(var j=1;j<length;j++){ f+=sum-length*A[length-j]; max=Math.max(f,max); } return max; };
解法二:
分析:
F(k) - F(k-1) = nA[k-1]-sum;
var maxRotateFunction = function(A) { var f=0; var sum=0; var max; var length=A.length; for(var i=0;i<length;i++){ f+=i*A[i]; sum+=A[i]; } max=f; for(var j=1;j<length;j++){ f+=(length*A[j-1]-sum); max=Math.max(f,max); } return max; };
题目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.
Example:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].
解法:
var twoSum = function(nums, target) { var number=[0,0]; for(var i=0;i<nums.length;i++){ number[0]=i; var second_index=nums.indexOf(target-nums[i],i+1); if(second_index>-1){ number[1]=second_index; return number; } } return number; };