1. https://leetcode-cn.com/problems/two-sum/

时间复杂度:0(n²)

  1. var twoSum = function (nums, target) {
  2. if (nums.length < 1) return false;
  3. for (let i = 0; i < nums.length - 1; i++) {
  4. for(let j = i+1; j < nums.length; j++){
  5. if(nums[i] + nums[j] === target){
  6. return [j,i]
  7. }
  8. }
  9. }
  10. };

优化:时间复杂度:0(n)

  1. var twoSum = function(nums, target) {
  2. const map = new Map()
  3. for(let i = 0; i < nums.length; i+=1){
  4. const n = nums[i]
  5. let n2 = target - n
  6. if(map.has(n2)){
  7. return [map.get(n2),i]
  8. }else{
  9. map.set(n,i)
  10. }
  11. }
  12. };

2. https://leetcode-cn.com/problems/move-zeroes/

时间复杂度:0(n)
思路:利用快慢指针进行位置交换

  1. var moveZeroes = function(nums) {
  2. let j = 0;
  3. for(let i = 0; i < nums.length; i++){
  4. if(nums[i] !== 0){
  5. if(i!==j){
  6. [nums[j],nums[i]] = [nums[i],nums[j]]
  7. }
  8. j++
  9. }
  10. }
  11. return nums
  12. };

时间复杂度:0(n)
思路:将所有非0移入前面,在后面补0

  1. var moveZeroes = function(nums) {
  2. let j = 0
  3. for(let i = 0; i < nums.length; i++){
  4. if(nums[i]!==0){
  5. nums[j] = nums[i]
  6. if(i!=j){
  7. nums[i] = 0
  8. }
  9. j++
  10. }
  11. }
  12. return nums
  13. };

3. https://leetcode-cn.com/problems/container-with-most-water/submissions/

时间复杂度:0(n)
思路:枚举 left,right,(right-left) * height。
双指针,左右边界向中间收敛,确定一个最左边位置和一个最右边位置,判断左右两边的height哪个小向中间移动哪个。计算出最大的那个面积。

  1. var maxArea = function(height) {
  2. let max = 0;
  3. let j = height.length - 1
  4. let i = 0
  5. while(i<j){
  6. let minHeight = height[i] < height[j] ? height[i++] : height[j--]
  7. let area = (j-i+1) * minHeight
  8. max = Math.max(max,area)
  9. }
  10. return max
  11. };

4. https://leetcode-cn.com/problems/climbing-stairs/

时间复杂度:0(n)
思路:爬第三阶台阶可以从第一阶台阶跨两步走上去,也可以从第二阶台阶跨一步走上去。f(3) = f(2) + f(1)
同理上第n阶台阶f(n) = f(n-1) + f(n-2)

  1. var climbStairs = function(n) {
  2. let f1 = 1,f2 = 2,f3 = 3
  3. if( n < 3 ) return n
  4. for(let i = 3; i <= n; i++){
  5. f3 = f1 + f2
  6. // 维护f1和f2
  7. f1 = f2
  8. f2 = f3
  9. }
  10. return f3
  11. };

5. https://leetcode-cn.com/problems/3sum/

时间复杂度:0(n²)
思路:两边向中夹,首先进行从小到大排序,首先确定k和i的位置在最左边,j的位置在最右边,如果相加的和大于0,则右边向左边移动,反之。确定好每一步的去重操作。

  1. /**
  2. * @param {number[]} nums
  3. * @return {number[][]}
  4. */
  5. var threeSum = function(nums) {
  6. let res = []
  7. if(nums && nums.length < 3) return res
  8. nums.sort((a,b) => a-b)
  9. for(let k = 0 ;k < nums.length-2; k++){
  10. if(nums[k] > 0) break; // 如果当前数字大于0,则三数之和一定大于0,所以结束循环
  11. if(k > 0 && nums[k] == nums[k-1]) continue; // 去重
  12. let i = k + 1;
  13. let j = nums.length - 1
  14. while(i < j){
  15. let sum = nums[k] + nums[i] + nums[j]
  16. if(sum < 0){
  17. i++
  18. }else if(sum > 0){
  19. j--
  20. }else{
  21. res.push([nums[k],nums[i],nums[j]])
  22. while(i<j && nums[i] === nums[++i]);
  23. while(i<j && nums[j] === nums[--j]);
  24. }
  25. }
  26. }
  27. return res
  28. };

6. https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array/

时间复杂度:0(n)
思路:快慢指针,当nums[i] !== nums[j],把nums[j]的值放到nums[i+1]

  1. var removeDuplicates = function(nums) {
  2. let i = 0;
  3. for(let j = 1; j< nums.length; j++){
  4. if(nums[i] !== nums[j]){
  5. i++
  6. nums[i] = nums[j]
  7. }
  8. }
  9. return i+1
  10. };

7. https://leetcode-cn.com/problems/rotate-array/

时间复杂度:0(n)
思路:首先进行整个翻转,从第k个元素切割,左右两边各自翻转

  1. function reverse (nums,start,end){
  2. while(end > start){
  3. [nums[start++],nums[end--]] = [nums[end],nums[start]]
  4. }
  5. }
  6. var rotate = function(nums, k) {
  7. if(nums.length < 2) return nums
  8. k %= nums.length
  9. reverse(nums, 0, nums.length - 1);
  10. reverse(nums, 0, k - 1);
  11. reverse(nums, k, nums.length - 1);
  12. return nums
  13. };

8. https://leetcode-cn.com/problems/merge-sorted-array/

双指针时间复杂度:0(n)

  1. const merge = function (nums1, m, nums2, n) {
  2. let i = m - 1, j = n - 1, k = m + n - 1
  3. while (i >= 0 && j >= 0) {
  4. if (nums1[i] >= nums2[j]) {
  5. nums1[k] = nums1[i]
  6. i--
  7. k--
  8. } else {
  9. nums1[k] = nums2[j]
  10. j--
  11. k--
  12. }
  13. }
  14. while (j >= 0) {
  15. nums1[k] = nums2[j]
  16. k--
  17. j--
  18. }
  19. return nums1
  20. };
  1. var merge = function(nums1, m, nums2, n) {
  2. nums1.splice(m)
  3. nums2.splice(n)
  4. nums1.push(...nums2)
  5. nums1.sort((a,b)=>a-b)
  6. };

9. https://leetcode-cn.com/problems/plus-one/

时间复杂度:0(n)
思路:倒序循环,每次循环都进行对10取余操作,如果不等于0说明不大于10,直接返回,否则等于10,前面补1。

  1. var plusOne = function(digits) {
  2. const len = digits.length;
  3. for(let i = len - 1; i >= 0; i--) {
  4. digits[i]++;
  5. digits[i] %= 10;
  6. if(digits[i]!=0)
  7. return digits;
  8. }
  9. digits = [1,...digits]
  10. digits[0] = 1;
  11. return digits;
  12. };

10. https://leetcode-cn.com/problems/intersection-of-two-arrays-ii/

为两个数组分别建立 map,用来存储 num -> count 的键值对,统计每个数字出现的数量。
然后对其中一个 map 进行遍历,查看这个数字在两个数组中分别出现的数量,取出现的最小的那个数量(比如数组 1 中出现了 1 次,数组 2 中出现了 2 次,那么交集应该取 1 次),push 到结果数组中即可。

  1. /**
  2. * @param {number[]} nums1
  3. * @param {number[]} nums2
  4. * @return {number[]}
  5. */
  6. var intersect = function (nums1, nums2) {
  7. const map1 = makCountMap(nums1)
  8. const map2 = makCountMap(nums2)
  9. const res = []
  10. for (let num of map1.keys()) {
  11. const count1 = map1.get(num)
  12. const count2 = map2.get(num)
  13. if (count2) {
  14. const pushCount = Math.min(count1, count2)
  15. for (let i = 0; i < pushCount; i++) {
  16. res.push(num)
  17. }
  18. }
  19. }
  20. return res
  21. };
  22. function makCountMap(nums) {
  23. let map = new Map()
  24. for (let i = 0; i < nums.length; i++) {
  25. let num = nums[i]
  26. let count = map.get(num)
  27. if (count) {
  28. map.set(num, count + 1)
  29. } else {
  30. map.set(num, 1)
  31. }
  32. }
  33. return map;
  34. }