算法小平常-03

【5】最長迴文串

重點回顧題
題外話:多是之前參加ACM比賽時,被一道須要利用動態規劃的題絆住了,致使到如今爲止,只要看到跟動態規劃有關的題,就打怵😂,這是留下了多大的陰影啊
假設當前判斷的迴文是從第 0 個字符,到第 4 個字符,那麼就是推導 s[0] === s[4] && s[1-3] 是迴文。
定義二維數組 dp,橫座標表示起始字符,縱座標表示當前新加入字符,獲得 dpi = s[i] === s[j] && dpi-1。
時間複雜度是 O(n*n/2)算法

var longestPalindrome = function(s) {
  if (s === '') return ''
  
  let arr = s.split('')
  let dp = new Array(arr.length).fill([])
  for (let i = 0; i < dp.length; i++) {
    dp[i] = new Array(arr.length).fill(false)
  }

  let max = 1
  let maxStart = 0
  let maxEnd = 0
  
  for (let i = 0; i < arr.length; i++) {
    for (let j = 0; j <= i; j++) {
      if (i === j) {
        dp[i][j] = true
      }

      if (i - j === 1) {
        dp[i][j] = arr[i] === arr[j]
        if (dp[i][j] && max < 2) {
          max = 2
          maxStart = j
          maxEnd = i
        }
      }

      if (i - j > 1) {
        dp[i][j] = arr[i] === arr[j] && dp[i-1][j+1]
        const len = i - j + 1
        if (dp[i][j] && max < len) {
          max = len
          maxStart = j
          maxEnd = i
        }
      }
    }
  }
  
  let result = ''
  for (let i = maxStart; i <= maxEnd; i++) {
    result += arr[i]
  }
  return result
};

【8】字符串轉換整數(atoi)

本題須要注意有符號和無符號,還有存儲範圍,按照程序化一步步操做就好數組

var myAtoi = function (str) {
    const numreg = /^[0-9]*$/

    const num = str.trim()
    const result = parseInt(str) || 0


    if (isNaN(result)) {
        return 0;
    }
    if (num[0] == '-') {
        const min = Math.pow(-2, 31)
        return result < min ? min : result
    }
    else if (numreg.test(num[0]) || num[0] == '+') {//開頭是數字
        const max = Math.pow(2, 31) - 1
        return result > max ? max : result
    }
    else {
        return 0;
    }
};

也能夠用parseInt來處理指針

var myAtoi = function(str) {
    str = str.trim();
    var max = Math.pow(2,31)-1;
    var min = -Math.pow(2,31);
    str = parseInt(str);
    if(str>=max){
        return max;
    }
    if(str<=min){
        return min;
    }
    if(isNaN(str)){
        return 0;
    }else{
        return str;
    }
};

【11】 盛最多水的容器

初看,轉換成數學題,是求最大面積,因此又是一道動態規劃題
看了官方題解的思路,雙指針法是最優解法code

var maxArea = function(height) {
    let left = 0;
    let right = height.length - 1;
    let max = 0;
    while(left < right) {
        const area = (right - left) * Math.min(height[right], height[left]);
        if (area > max) {
            max = area
        }
        if (height[left] < height[right]) {
            
            left++;
            
        } else {
            
            right--;
           
        }
    }
    return max;
};

【238】除自身之外數組的乘積

看上去不難,可是有額外要求 :不要使用除法,且在 O(_n_) 時間複雜度
思路:記錄每一個元素左面全部元素的乘積(不包括自身)
右邊的乘積不須要記錄,直接和左面乘積相乘字符串

/**
 * @param {number[]} nums
 * @return {number[]}
 */
var productExceptSelf = function (nums) {
  let v = 1
  let result=[1]
  for (let i = 1; i < nums.length; i++) {
    v *= nums[i - 1]
    result[i] = v
  }
   v = 1
  for (let i = nums.length - 1; i > 0; i--) {
    v *= nums[i]
    result[i - 1] *= v
  }
  return result
};

【78】子集

給定一組不含重複元素的整數數組 _nums_,返回該數組全部可能的子集(冪集)。數學

說明:解集不能包含重複的子集。
看到 「子集」、「組合」這樣的詞語,首先想到回溯算法。
全排列:N!
組合:N!
子集:2^N ,每一個元素均可能存在或不存在。it

var subsets = function(nums) {
    const n = nums.length;
    const result = [];
    if (nums.length < 1) return [[]];
    const backTrace = (arr, currentIndex) => {
        result.push(arr);
        if (currentIndex >= n) return;
        for (let i = currentIndex; i < n; ++i) {
            arr.push(nums[i]);
            backTrace(arr.slice(), i+1);
            arr.pop();
        }
    }
    backTrace([], 0);
    return result;
};

小結:果真上了中等難度後,就真的開始變難了,很久不碰算法,記憶都模糊了,加油~io

相關文章
相關標籤/搜索