两数之和
/**
* @param {number[]} nums
* @param {number} target
* @return {number[]}
*/
var twoSum = function(nums, target) {
for(let i = 0; i < nums.length;i++ ){
for(let j = i + 1;j < nums.length ;j++){
if(target === nums[i] + nums[j]){
return [i,j]
}
}
}
}
var twoSum = function(nums, target) {
let map = new Map();
for (let i = 0; i < nums.length; i++) {
let dif = target-nums[i]
if (map.has(dif)) {
return [map.get(dif), i]
}
map.set(nums[i], i);
}
};
罗马字符数字转整数
/**
* @param {string} s
* @return {number}
*/
let Num = {
I:1,
V:5,
X:10,
L:50,
C:100,
D:500,
M:1000,
IV:4,
IX:9,
XL:40,
XC:90,
CD:400,
CM:900
}
var romanToInt = function(s) {
let sum = 0
for(let i = 0;i < s.length ;i++){
if(i < s.length && Num[s[i] + s[i+1]]){
sum += Num [s[i] + s[i+1]]
i += 1
}else{
sum += Num[s[i]]
}
}
return sum
};
反转字符串
必须原地修改输入数组、使用 O(1) 的额外空间
/**
Do not return anything, modify s in-place instead.
*/
function reverseString(s: string[]): void {
s = s.reverse()
};
整数反转
/**
* @param {number} x
* @return {number}
*/
var reverse = function(x) {
let newX = x.toString()
let sum
if(newX[0]==='-'){
sum = newX[1]*1
for(let i = 2;i<newX.length;i++){
sum += newX[i]*Math.pow(10,i-1)
}
sum*=-1
}else{
sum = newX[0]*1
for(let i = 1; i<newX.length;i++){
sum += newX[i]*Math.pow(10,i)
}
}
if ( sum < - Math.pow(2, 31) || sum > Math.pow(2, 31) - 1){
return 0
}
return sum
};
加一
给定一个由 整数组成的非空 数组所表示的非负整数,在该数的基础上加一。
最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。 你可以假设除了整数 0 之外,这个整数不会以零开头。
function plusOne(digits: number[]): number[] {
for(let i = digits.length -1;i>=0;i--){
digits[i]+=1
digits[i]%=10
if(digits[i]!==0){
return digits
}
}
digits.unshift(1)
return digits
};
旋转数组
给你一个数组,将数组中的元素向右轮转 k个位置,其中 k是非负数。
/**
Do not return anything, modify nums in-place instead. Way One
*/
function rotate(nums: number[], k: number): void {
for(let i:number =0;i<k;i++){
nums.unshift(nums.pop())
}
};
/**
Do not return anything, modify nums in-place instead. Way Two 使用临时数组
*/
function rotate(nums: number[], k: number): void {
let newNums:number []=[]
let length = nums.length
for(let i = 0;i<length;i++){
newNums[i] = nums[i]
}
for(let i = 0;i<length;i++){
nums[(i+k)%length] = newNums[i]
}
};
存在重复元素
给你一个整数数组 nums 。如果任一值在数组中出现 至少两次 ,返回 true ;如果数组中每个元素互不相同,返回 false 。
//方法一
function containsDuplicate(nums: number[]): boolean {
let arr:number [] = [...new Set(nums)]
return arr.length !== nums.length
};
//方法二
function containsDuplicate(nums: number[]): boolean {
nums.sort((a,b)=>a-b)
for(let i = 0;i<nums.length;i++){
if(nums[i]===nums[i+1]) return true
}
return false
};
只出现一次的数字
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
function singleNumber(nums: number[]): number {
nums.sort((a,b)=>a-b)
for(let i = 0;i<nums.length;i++){
if(nums[i]===nums[i+1]){
i++
}else {
return nums[i]
}
}
};
二分法查找
function search(nums: number[], target: number): number {
let numsLength = nums.length
if(!numsLength) return -1
if(numsLength === 1){
return nums[0] === target ? 0:-1
}
let start=0,end=numsLength - 1
while(start<=end){
let mid = Math.floor((start+end)/2) //取中位数d
if(nums[mid] === target){
return mid
}else if (target > nums[mid]){ //目标数比中位数大,移动初始值start边界
start = mid + 1
}else {
end = mid - 1 //目标数比中位数小,移动初始值end边界
}
}
return -1
};
寻找数组的中心索引
/**
* @param {number[]} nums
* @return {number}
*/
var pivotIndex = function(nums) {
const total = nums.reduce((pre,cur)=>pre+=cur,0)
let number = -1
let left = 0
for(let i=0;i<nums.length;i++){
left += nums[i]
console.log(left,'left',total-nums[i]-left)
if(left === total + nums[i] - left){
number = i
break;
}
}
return number
};
function pivotIndex(nums: number[]): number {
let number = -1,sum=0
const total = nums.reduce((pre,cur)=>pre+=cur,0)
nums.some((cur,index)=>{
sum+=cur
if(sum === total + cur - sum){
number = index
return true
}
})
return number
};
搜索插入位置
function searchInsert(nums: number[], target: number): number {
let result:number
nums.some((cur,index)=>{
if(cur >= target) {
result = index
return true
}
})
return result ?? nums.length
};
function searchInsert(nums: number[], target: number): number {
let result:number
if(nums[nums.length-1] < target) {
return nums.length
}else {
for(let i=0;i<nums.length;i++){
if(nums[i] >= target){
result = i
break
}
}
}
return result
};
合并区间
/**
* @param {number[][]} intervals
* @return {number[][]}
*/
var merge = function (intervals) {
const sortNums = intervals.sort((a, b) => a[0] - b[0])
return sortNums.reduce((pre, cur) => {
const arr = pre[pre.length - 1]
if (arr && arr[1] >= cur[0]) {
let left = arr[0]
let right = arr[1] <= cur[1] ? cur[1] : arr[1]
pre[pre.length - 1] = [left,right]
} else {
pre.push(cur)
}
return pre
}, [])
};
删列造序
/**
* @param {string[]} strs
* @return {number}
*/
var minDeletionSize = function(strs) {
let number = 0
const arr = strs[0].split('').map((item,index)=> strs.map(_item=> _item[index]))
for(let item of arr) {
for(let i=0;i<item.length-1;i++){
if(item[i] > item[i+1]){
number ++
break;
}
}
}
return number
};
旋转矩阵
/**
* @param {number[][]} matrix
* @return {void} Do not return anything, modify matrix in-place instead.
*/
var rotate = function(matrix) {
const arr = matrix.reverse()
for(let i = 0;i<arr.length ;i++){
for(let j = i;j<arr[i].length;j++){
let temp = arr[i][j]
arr[i][j] = arr[j][i]
arr[j][i] = temp
}
}
return arr
};
零矩阵
/**
* @param {number[][]} matrix
* @return {void} Do not return anything, modify matrix in-place instead.
*/
var setZeroes = function(matrix) {
let rowArr = [],columnArr = []
matrix.forEach((item,index)=>{
item.forEach((_item,_index)=>{
if(_item ===0) {
if(rowArr.indexOf(index) === -1) rowArr.push(index)
if(columnArr.indexOf(_index) === -1) columnArr.push(_index)
}
})
})
rowArr.forEach(item=>{
matrix[item] = matrix[item].map(item=>item = 0)
})
columnArr.forEach(item=>{
for(let i =0;i<matrix.length;i++){
matrix[i][item] = 0
}
})
return matrix
};
最大三角形面积
/**
* @param {number[][]} points
* @return {number}
*/
var largestTriangleArea = function(points) {
let maxArea = 0
const getArea = ([x1,y1],[x2,y2],[x3,y3]) => {
const area = (x1*(y2-y3)+x2*(y3-y1)+x3*(y1-y2))/2
return area > 0 ? area : -1 * area
}
for(let i=0;i < points.length;i++){
for(let j= i + 1;j < points.length;j++){
for(let k = j + 1;k < points.length;k++){
const areaInfo = getArea(points[i],points[j],points[k]);
if(areaInfo >= maxArea) maxArea = areaInfo
}
}
}
return maxArea
};
最长公共前缀
/**
* @param {string[]} strs
* @return {string}
*/
var longestCommonPrefix = function(strs) {
for(let i=0;i<strs[0].length;i++){
let s = strs[0][i]
for(let j=1;j<strs.length;j++){
if(strs[j][i] !== s) {
return strs[0].slice(0,i)
}
}
}
return strs[0]
};
翻转字符串中的单词
/**
* @param {string} s
* @return {string}
*/
var reverseWords = function(s) {
return s.split(' ').filter(item=>item!=='').reverse().join(' ')
};
数组拆分 I
/**
* @param {number[]} nums
* @return {number}
*/
var arrayPairSum = function(nums) {
const arr = nums.sort((a,b)=>a-b)
let total = 0
for(let i=0;i<arr.length;){
total += arr[i]
i+=2
}
return total
};
最长回文子串
通过遍历查找每个字符的左右边界且相等的情况下,返回边界值,如果边界的长度大于原先的边界则覆盖。但考虑到字符串的长度可能是奇数或者偶数,考虑中心点可能是1个或者2个。
/**
* @param {string} s
* @return {string}
*/
var longestPalindrome = function(s) {
const expandeAroundCenter = (s,left,right)=>{
while(left >= 0 && right < s.length && s[left]===s[right]){
left--
right++
}
return [left+1,right-1]
}
let start=0,end=0
for(let i=0;i<s.length;i++){
const [left1,right1] = expandeAroundCenter(s,i,i)
const [left2,right2] = expandeAroundCenter(s,i,i+1)
if(right1-left1>end-start){
end = right1
start = left1
}
if(right2-left2>end-start){
end = right2
start = left2
}
}
return s.slice(start,end+1)
}
杨辉三角 I
/**
* @param {number} numRows
* @return {number[][]}
*/
var generate = function(numRows) {
let arr = [[1]]
if(numRows===1){
return arr
} else if(numRows===2){
arr.push([1,1])
return arr
} else {
arr.push([1,1])
for(let i=2;i<numRows;i++) {
let x = [1]
for(let j=0;j < arr[i-1].length - 1;j++){
x.push(arr[i-1][j] + arr[i-1][j+1])
}
x.push(1)
arr.push(x)
}
return arr
}
}
/**
* @param {number} numRows
* @return {number[][]}
*/
var generate = function(numRows) {
let total = []
for(let i = 0;i < numRows;i++){
let arr = new Array(i+1).fill(1)
for(let j = 1;j < arr.length - 1;j++){
arr[j] = total[i-1][j-1] + total[i-1][j]
}
total.push(arr)
}
return total
};
/**
* @param {number} numRows
* @return {number[][]}
*/
var generate = function(numRows) {
let total = []
const getRow = (index) =>{
let row = new Array(index).fill(0)
row[0] = 1
for(let i=1;i<=index;i++){
row[i] = row[i-1] * (index - i + 1) / i
}
return row
}
for(let i = 0;i < numRows;i++){
const row = getRow(i)
total.push(row)
}
return total
};
杨辉三角 II
返回第n行的数组
/**
* @param {number} rowIndex
* @return {number[]}
*/
var getRow = function(rowIndex) {
let total = []
for(let i=0;i<rowIndex+1;i++){
let arr = new Array(i+1).fill(1)
for(let j = 1;j < arr.length - 1;j++){
arr[j] = total[i-1][j-1] + total[i-1][j]
}
total.push(arr)
}
return total[rowIndex]
};
/**
* @param {number} rowIndex
* @return {number[]}
*/
var getRow = function(rowIndex) {
let rowArr = new Array(rowIndex + 1).fill(0)
rowArr[0] = 1
for(let i=1;i <= rowIndex; i++){
rowArr[i] = rowArr[i - 1] * (rowIndex - i + 1) / i
}
return rowArr
};
反转字符串中的单词 III
- **输入:**s = "Let's take LeetCode contest"
- 输出:"s'teL ekat edoCteeL tsetnoc"
/**
* @param {string} s
* @return {string}
*/
var reverseWords = function(s) {
const arr = s.split(' ')
for(let i=0;i<arr.length;i++){
arr[i] = arr[i].split('').reverse().join('')
}
return arr.join(' ')
};
最大连续1的个数
/**
* @param {number[]} nums
* @return {number}
*/
var findMaxConsecutiveOnes = function(nums) {
const arr = nums.join('').split(0)
let max = 0
for(let i=0;i<arr.length;i++){
const length = arr[i].length
max = length > max ? length : max
}
return max
};
const findMaxConsecutiveOnes = (nums) => {
let maxCount=0,count=0
for(let i = 0;i < nums.length;i++){
if(nums[i] === 1){
count++
} else {
maxCount = Math.max(maxCount,count)
count = 0
}
}
return Math.max(maxCount,count)
}
移除元素
给你一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,并返回移除后数组的新长度。
const removeElement = (nums,val) => {
let i = 0
nums.forEach((item,index)=>{if(item !==val) nums[i++] = nums[index]})
return i
}
const removeElement = (nums,val) => {
let left=0,right= nums.length
while(left < right){
if(nums[left] === val){
nums[left] = nums[right-1]
right--
} else {
left++
}
}
return left
}
移动零
快指针遇到非零数,则和慢指针指向的零交换位置。
const moveZeros = (nums) =>{
let slow = 0
for(let fast = 0;fast < nums.length;fast++){
if(nums[fast]){
let temp = nums[slow]
nums[slow] = nums[fast]
nums[fast] = temp
slow++
}
}
return nums
}
实现strStr()
给你两个字符串haystack
和needle
,请你在haystack
字符串中找出needle
字符串的第一个匹配项的下标(下标从 0 开始)。如果needle
不是haystack
的一部分,则返回 -1 。
/**
* @param {string} haystack
* @param {string} needle
* @return {number}
*/
var strStr = function(haystack, needle) {
for (let i=0;i<haystack.length;i++) {
const needleLength = needle.length
const haystackLength = haystack.length
if (haystackLength >= needleLength + i) {
const copy = haystack.slice(i,needleLength + i)
if(copy === needle) {
return i
}
}
}
return -1
};
寻找旋转排序数组中的最小值
必须使用O(log n)
的时间复杂度
/**
* @param {number[]} nums
* @return {number}
*/
var findMin = function(nums) {
if(nums.length === 1) return nums[0]
let l=0,r = nums.length - 1
while(l<r) {
let mid = Math.floor((l+r)/2)
if(nums[mid]>nums[r]) {
l = mid + 1;
} else {
r = mid
}
}
return nums[l]
};
树结构树节点查找本层深度
/**
* 查看树中Object的嵌套深度
* @param {number} id
* @return {number}
*/
function getTreeMaxFloor(findId) {
let toggle = false
let max = 1
let result = 1
const callBack = (findId, data) => {
for (let i = 0; i < data.length; i++) {
const { id, type, children } = data[i]
if (type === 'Object') {
if (findId !== id && children.length > 0) {
max += 1
callBack(findId, children)
} else if (findId === id) {
toggle = true
result = max
}
}
}
max = toggle ? result : 1
}
callBack(findId, this.treeData)
return result
}
K 件物品的最大和
/**
* @param {number} numOnes
* @param {number} numZeros
* @param {number} numNegOnes
* @param {number} k
* @return {number}
*/
var kItemsWithMaximumSum = function(numOnes, numZeros, numNegOnes, k) {
return numOnes > k
? k
: numOnes + numZeros < k ? 2 * numOnes + numZeros - k : numOnes
};
矩阵中的和
/**
* @param {number[][]} nums
* @return {number}
*/
var matrixSum = function(nums, x = 0) {
let total = x
let curMax = 0
for (let i = 0; i < nums.length; i++){
const numsList = nums[i]
const { max, maxIndex } = getMaxNumber(numsList)
numsList.splice(maxIndex, 1)
if (max > curMax) curMax = max
}
total += curMax
return nums[0].length === 0 ? total : matrixSum(nums, total)
};
var getMaxNumber = (arr) => {
let max = 0
let maxIndex = -1
for (let i = 0; i < arr.length; i++) {
const cur = arr[i]
if (max < cur) {
max = cur
maxIndex = i
}
}
return { max, maxIndex }
}
拆分成最多数目的正偶数之和
function maximumEvenSplit(finalSum: number): number[] {
if (finalSum % 2 !== 0) return []
let arr: number[] = []
for (let i = 2; i <= finalSum; i+=2) {
arr.push(i)
finalSum -= i
}
arr[arr.length - 1] += finalSum
return arr
}
两数之和 II - 输入有序数组
原理:通过双向双指针,因为原数组是经过排序的,时间复杂度O(n)
function twoSum(numbers: number[], target: number): number[] {
let l = 0, r = numbers.length - 1
while (numbers[l] + numbers[r] !== target) {
numbers[l] + numbers[r] < target ? l++ : r--
}
return [l+1, r+1]
};