给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
例子:
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
解题思路:
(1)暴力枚举:枚举数组中的每一个数 x,寻找数组中是否存在 target - x
(2)哈希表:我们创建一个哈希表,对于每一个 x,我们首先查询哈希表中是否存在 target - x,然后将 x 插入到哈希表中,即可保证不会让 x 和自己匹配。
var twoSum = function(nums, target) {
//暴力枚举方法1
/*for(let i=0;i
//暴力枚举方法2
for(let i=0;i<nums.length;i++){
let temp = target - nums[i]
let j = nums.indexOf(temp)
if(j != -1 && j != i) return [i,j]
}
return [-1, -1]
};
var twoSum = function(nums, target) {
let hashTable = {}
for(let i=0; i<nums.length; i++){
let temp = target-nums[i]
// if(hashTable.hasOwnProperty(temp)) {
if(temp in hashTable) {
return [hashTable[temp], i]
}
hashTable[nums[i]] = i
}
return []
};
给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false
回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
例如,121 是回文,而 123 不是。
解题思路:
(1)转成字符串,逐步判断前后数字是否相等
(2)将数字本身反转,然后将反转后的数字与原始数字进行比较,如果它们是相同的,那么这个数字就是回文。
var isPalindrome = function(x) {
//1.基础方法 转成字符串,遍历进行判断
let s = x.toString().split('')
for(let i=0; i<s.length/2;i++){
if(s[i] != s[s.length-1-i]) return false
}
return true
var isPalindrome = function(x) {
//2.官方算法思路 反转数字进行判断
// (1)负数和最后一位数字为0(0除外)的肯定不是回文数
if(x === 0) return true
if(x < 0 || x % 10 === 0) return false
//(2)从后往前取除以10的商和余数,计算反转后的数,当反转后的数大于等于商时,就取完了一半的数,可以停止了
let quotient = x
let remainder = 0
let revert = 0
while(revert < quotient){
remainder = quotient % 10
quotient = Math.floor(quotient / 10)
revert = revert * 10 + remainder
// console.log(remainder, quotient, revert)
}
//这一步之前没想到
if(revert === quotient || quotient === Math.floor(revert / 10)) return true
return false
};
官方题解
var isPalindrome = function(x: number): boolean {
// 特殊情况:
// 如上所述,当 x < 0 时,x 不是回文数。
// 同样地,如果数字的最后一位是 0,为了使该数字为回文,
// 则其第一位数字也应该是 0
// 只有 0 满足这一属性
if (x < 0 || (x % 10 === 0 && x !== 0)) {
return false;
}
let revertedNumber: number = 0;
while (x > revertedNumber) {
revertedNumber = revertedNumber * 10 + x % 10;
x = Math.floor(x / 10);
}
// 当数字长度为奇数时,我们可以通过 revertedNumber/10 去除处于中位的数字。
// 例如,当输入为 12321 时,在 while 循环的末尾我们可以得到 x = 12,revertedNumber = 123,
// 由于处于中位的数字不影响回文(它总是与自己相等),所以我们可以简单地将其去除。
return x === revertedNumber || x === Math.floor(revertedNumber / 10);
};
罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。
字符 数值
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
例如, 罗马数字 2 写做 II ,即为两个并列的 1 。12 写做 XII ,即为 X + II 。 27 写做 XXVII, 即为 XX + V + II 。
通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况:
I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。
C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。
给定一个罗马数字,将其转换成整数。
示例 1:
输入: s = “III”
输出: 3
示例 2:
输入: s = “IV”
输出: 4
解题思路:
(1)遍历字符串,先把六种特殊情况给计算并替换为空,再计算普通情况
(2) 遍历的时候进行上一位的加减,上一位小于本位则在总和上减,否则则加
// @lc code=start
/**
* @param {string} s
* @return {number}
*/
var romanToInt = function(s) {
let objSpecial = {
'IV': 4,
'IX': 9,
'XL': 40,
'XC': 90,
'CD': 400,
'CM': 900,
}
let objNormal = {
'I': 1,
'V': 5,
'X': 10,
'L': 50,
'C': 100,
'D': 500,
'M': 1000
}
// 方法一
let str = s
//获取字符串中特殊的字符
let sum = 0
Object.entries(objSpecial).forEach(([key, value]) => {
let num = 0
let index = str.indexOf(key)
while(index != -1) {
num += 1
str = str.replace(key,'')
index = str.indexOf(key)
}
sum += num*value
});
Object.entries(objNormal).forEach(([key, value]) => {
let num = 0
let index = str.indexOf(key)
while(index != -1) {
num += 1
str = str.replace(key,'')
index = str.indexOf(key)
}
sum += num*value
});
// // console.log(sum);
return sum
};
// @lc code=start
/**
* @param {string} s
* @return {number}
*/
var romanToInt = function(s) {
let objSpecial = {
'IV': 4,
'IX': 9,
'XL': 40,
'XC': 90,
'CD': 400,
'CM': 900,
}
let objNormal = {
'I': 1,
'V': 5,
'X': 10,
'L': 50,
'C': 100,
'D': 500,
'M': 1000
}
//方法二-多判断一位,右边大于左边就减,否则就加
let sum = 0
let pre = ''
for (let i=0; i< s.length; i++){
if(pre == '') {
pre = s[i]
continue
}
if(objNormal[s[i]] > objNormal[pre]){
sum -= objNormal[pre]
}
else{
sum += objNormal[pre]
}
pre = s[i]
}
sum += objNormal[s[s.length-1]]
return sum
};
编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 “”。
示例 1:
输入:strs = [“flower”,“flow”,“flight”]
输出:“fl”
示例 2:
输入:strs = [“dog”,“racecar”,“car”]
输出:“”
解释:输入不存在公共前缀。
解题思路:
先获取所有字符串的最小长度,分别对字符串进行遍历,并将对应index的字符保存在一个数组中,如果数组所有元素都相同,则进行公共前缀的拼接,执行下一次循环,否则则退出循环,返回结果
// @lc code=start
/**
* @param {string[]} strs
* @return {string}
*/
var longestCommonPrefix = function(strs) {
let commonStr = ''
let minLen = Math.min(...strs.map(function(eleStr){
return eleStr.length
}))
for(let i=0; i< minLen; i++){
let s = []
strs.forEach(ele=>{
s.push(ele[i])
})
if(s.every(item=>item==s[0])){
commonStr += s[0]
}else{
break
}
}
return commonStr
};
给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
每个右括号都有一个对应的相同类型的左括号。
示例 1:
输入:s = “()”
输出:true
示例 2:
输入:s = “()[]{}”
输出:true
示例 3:
输入:s = “(]”
输出:false
解题思路:
遍历字符串,遇到左括号则压入保存进数组,遇到右括号,则进行判断:
(1)判断是否在right中,获取右括号在right数组中的index
(2)判断数组中的最后一位,与left[index]是否相等,相等则进行pop,否则则不匹配,跳出循环
最后根据flag和数组长度是否等于0来进行结果判断
// @lc code=start
/**
* @param {string} s
* @return {boolean}
*/
var isValid = function(s) {
let left = ['(', '[', '{']
let right = [')', ']', '}']
let arr = []
let flag = true
for(let i=0; i<s.length; i++){
//ES6新增的数组方法,用于检测数组是否包含某个元素,如果包含返回true,否则返回false,比较厉害的是,能直接检测NaN
if(left.includes(s[i])) {
arr.push(s[i])
continue
}
let index = right.indexOf(s[i])
if(index != -1) {
if(arr[arr.length-1] == left[index]){
arr.pop()
continue
}
else{
flag = false
break
}
}
}
return flag && arr.length == 0
};