常見的JavaScript面試演算法

星夢花隨0823發表於2018-11-26

斐波那契數列

// Base
function Fibonacci1(n) {
    if (n === 1) {
        return 1
    }
    if (n === 2) {
        return 1
    }
    if (n > 2) {
        return Fibonacci1(n - 1) + Fibonacci1(n - 2)
    }
}

// More
function Fibonacci2(n) {
    if (n === 1 || n === 2) {
        return 1
    } else {
        var pre = 1
        var next = 1
        var target
        for (var i = 3; i <= n; i++) {
            target = pre + next
            pre = next
            next = target
        }
        return target
    }
}

var start = new Date().getTime()
console.log(Fibonacci1(30))       // 832040
var end = new Date().getTime()
console.log(end - start)         // 43

start = new Date().getTime()
console.log(Fibonacci2(30))      // 832040
end = new Date().getTime()
console.log(end - start)         // 0
複製程式碼
  • 上述寫了實現斐波那契數列的兩種方法,第一種方法用了遞迴;第二種方法用了迴圈賦值;通過上述實踐,可以看出第二種方式的時間空間複雜度很小很小。所以,在此推薦用第二種方法實現斐波那契數列

字串反轉

var strChar = 'wangsuoling'

// Base
function strReserve1 (str) {
  if (typeof str !== 'string') {
    return false
  } else {
    var result = ''
    // 字串通過索引取值,IE7及其以前的版本不支援
    for (var i = str.length - 1; i >= 0 ; i--) {
      result += str[i]
    }
    return result
  }
}

// More
function strReserve2 (str) {
  if (typeof str !== 'string') {
      return false
  } else {
      let strNew = str.split('').reverse().join('')
      return strNew
  }
}

var start = new Date().getTime()
console.log(strReserve1(strChar))       // 'gnilousgnaw'
var end = new Date().getTime()
console.log(end - start)         // 31

start = new Date().getTime()
console.log(strReserve2(strChar))      // 'gnilousgnaw'
end = new Date().getTime()
console.log(end - start)         // 0
複製程式碼
  • 上述寫了實現字串反轉的兩種方法,通過上述實踐,可以看出第二種方式的時間空間複雜度很小很小。所以,在此推薦用第二種方法實現字串反轉

判斷字串是否是迴文

var str1 = 'abeffeba'
var str2 = 'abcdcba'
var str3 = 'abcd1234'

// Base
function huiWen1 (str) {
    for (let i = 0; i < str.length; i++) {
        if (str[i] === str[str.length - 1 - i]) {
            return true
        } else {
            return false
        }
    }
}

// Middle--利用棧 後進先出的特性
function huiWen2 (str) {
    var stackNewArr = [], len, mid, next, top
    len = str.length
    mid = Math.floor(len / 2 - 1)
    top = 0
    for (var i = 0; i <= mid; i++) {
        stackNewArr[++top] = str[i]
    }
    if (len % 2 === 0) {
        next = mid + 1
    } else {
        next = mid + 2
    }
    for (var j = next; j <= len-1; j++) {
        if (str[j] !== stackNewArr[top]) {
        break
        }
        top--
    }

    if (top === 0) {
        return true
    } else {
        return false
    }
}

// More
function huiWen3 (str) {
    let strNew = str.split('').reverse().join('')
    if (strNew === str) {
        return true
    } else {
        return false
    }
}

var start = new Date().getTime()
console.log(huiWen1(str2))       // true
var end = new Date().getTime()
console.log(end - start)         // 31

start = new Date().getTime()
console.log(huiWen2(str2))      // true
end = new Date().getTime()
console.log(end - start)         // 0

start = new Date().getTime()
console.log(huiWen3(str2))      // 'gnilousgnaw'
end = new Date().getTime()
console.log(end - start)         // 0
複製程式碼
  • 上述寫了實現判斷字串是否是迴文的三種方法,通過上述實踐,可以看出第二種方式 和 第三種方式 的時間空間複雜度很小很小。所以,在此推薦用第二種方法 或者 第三種方法實現字串反轉

陣列去重

// 思路:設定一個臨時陣列temp,然後遍歷要去重的陣列arr,如果arr中的元素能夠在temp中找到,則跳過此元素,否則將此元素存入temp,最後返回temp
// Base
function unique(arr){
    var temp = [];
    var len = arr.length;
    for(var i = 0; i < len; i++){
        if(temp.indexOf(arr[i]) === -1) temp.push(arr[i]);
    }    
    return temp;
}

// More
function unique( arr ) {
    var temp = [];
    var len = arr.length;
    for (var i = 0; i < len; i++) {
        var isRepeated = false;
        for ( var j = 0; j < temp.length; j++){
                if ( arr[i] === temp[j] ){                    
                       isRepeated = true;
                       break;
                   }
        }
        if ( !isRepeated ) temp.push( arr[i] );
    }
    return temp;
}

// 思路:設定一個臨時陣列temp,然後遍歷要去重的陣列arr,如果arr[i]中的元素在arr中出現的第一次的位置也為i,則將其存入temp,否則跳過此元素,最後返回temp
// Base
function unique(arr){
    var temp = [];
    var len = arr.length;
    for (var i = 0; i <len; i++){
        if(arr.indexOf([arr[i]) === i) temp.push(arr[i]);
    }
    return temp;
}

// 思路:設定一個臨時物件tempObj,然後遍歷要去重的陣列arr, 如果arr[i]中的元素在此物件中有標記,則跳過,否則在臨時物件中進行標記,並將其存入臨時陣列tempArr, 最後返回tempArr
// Base
function unique(arr){
    var tempObj = {};
    var tempArr = [];
    var len = arr.length;
    for (var i = 0; i < len; i++) {
        if ( !tempObj[arr[i]] ){
            tempObj[arr[i]] = true;
            tempArr.push(arr[i]);
        }
    }
    return tempArr;
}

// 思路:對要去重的陣列 arr 先進行排序,這樣重複的元素就排在了相鄰的位置,然後對陣列 arr 進行遍歷,將arr[i] 與 臨時陣列 temp 中的最後一個元素進行比較,如果不同則將其存入臨時陣列,如果相同則跳過此元素,最後返回臨時陣列。
// Base
function unique( arr ) {
    var temp = [];
    var len = arr.length;
    arr.sort();
    temp.push(arr[0]);
    for ( var i = 1; i < len; i++ ) {
        if ( arr[i] !== temp[temp.length-1] ) temp.push(arr[i]);
    }
    return temp;
}
複製程式碼

二分查詢

var find = function (arr, ele) {
    var start = 0;
    var end = arr.length - 1;

    while (end - start > 1){
        var mid =  parseInt((end + start) / 2);
        if(arr[mid] == ele){
            return true;
        } else if (arr[mid] > ele){
            end = mid - 1;
        } else {
            start = mid + 1;
        }
    }
    if(end - start == 1){
        if((arr[end] == ele) || (arr[start] == ele)){
            return true;
        }
    }
    return false;
}

var arr = [1, 3, 5, 6, 7, 9, 11]
var ele = 3

console.log(find(arr, ele))

複製程式碼

相關文章