JavaScript算法题

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/GreyBearChao/article/details/83106757

1. 给定一串数据将其转化为树形结构

// 数据:
 let arr = [
        {
            id: 1,
            name: 'js',
            parent:'前端'
        },
        {
            id: 2,
            name: '前端'
        },
        {
            id: 3,
            name: 'react',
            parent:'js'
        },
        {
            id: 4,
            name: 'jquery',
            parent:'js'
        },
        {
            id: 5,
            name: 'css3',
            parent:'css'
        },
        {
            id: 6,
            name: 'css',
            parent:'前端'
        }
    ];
// 方法一:非递归
<script>
    function findChild(arr, root) {
      var data = {}
      for (var i in arr) {
        data[arr[i].name] = arr[i]
      }
      for (var j in data) {
        if (data[j].parent) { // 该数据具有parent
          if (!data[data[j].parent].child) {
            data[data[j].parent].child = []
          }
          data[data[j].parent].child.push(data[j])
        } else {
          var res = Object.assign({}, data[j])
        }
      }
      return res
    }
    function findRoot(arr) {
      for (var i in arr) {
        if (!arr[i].parent) {
          return arr[i]
        }
      }
    }
    var root = findRoot(arr)
    console.log(findChild(arr))
  </script>

// 方法二: 递归
<script>
    function findChild(arr, parent) {
      var child = []
      for (var i in arr) {
        if (arr[i].parent && arr[i].parent === parent.name) {
          child.push(arr[i])
        }
      }
      if (child.length > 0) {
        parent.child = child
        for (var i in child) {
          findChild(arr, child[i])
        }
      }
    }
    function findRoot(arr) {
      for (var i in arr) {
        if (!arr[i].parent) {
          return arr[i]
        }
      }
    }
    var root = findRoot(arr);
    var obj = Object.assign({}, root);
    findChild(arr, obj)
    console.log(obj)
</script>

2. 对一个数组进行随机排序?

var arr = [1,2,3,4,5,6,7,8,9,10];
arr.sort(function(){
  return Math.random() - 0.5;
})
console.log(arr);

3. 求一段字符串中的最长回文字符串?

方法一:

思路:

  1. 提供一个函数用于判断一个字符串是否是回文字符串。
  2. 使用for循环,从第一个位置开始不断向后取字符直至最后,每取一次便判断其是否为回文字符串,然后从第二个位置开始不断向后取字符,依次类推。
<script>
    var str = "abddbahfjikgafghjjhgfalve"
    function isPalindrome(str) {
      return str === str.split('').reverse().join('')
    }
    function longestPalindrome(str) {
      var res = ''
      for (var i = 0; i < str.length; i++) {
        var temp = ''
        for (var j = i; j < str.length - 1; j++) {
          temp += str.charAt(j)
          if (isPalindrome(temp) && temp.length > res.length) {
            res = temp
          }
        }
      }
      return res
    }
    console.log(longestPalindrome(str))
</script>

// 判断一个字符串是否是回文字符串的另一种方法:
  function isPalindrome(str) {
      for (var i = 0, j = str.length - 1; i < j; i++, j--) {
        if (str.charAt(i) !== str.charAt(j)) {
          return false
        }
      }
      return true
    }

方法二:

思路:

  1. 只使用一层for循环遍历,先获取单个字符,设置指针i,j指向该字符,判断该字符左侧(i - 1)和右侧(j + 1)是否相等,如果相等,继续递减i,递增j判断。
  2. 需要处理形如 ‘aab’ 这样的字符串,应该返回 ‘aa’ ,而不是 ‘a’
var longestPalindrome = function(s) {
    var res = ''
    function checkPalindrome(l, r) {
        while(l >= 0 && r < s.length) {
            if (s[l] === s[r]) {
                l -= 1
                r += 1  
            } else {
                break
            }
        }
        l = l + 1
        r = r - 1
        if (res.length < r - l + 1) {
            res = s.substring(l, r + 1)
        }
    }
    for (var i = 0; i < s.length; i++) {
        if (i > 0 && s[i] === s[i - 1]) { // 处理形如 'aab' 这样的字符
            checkPalindrome(i, i - 1)
        }
        checkPalindrome(i, i) // 需要再次调用,否则 'aaa' 此类字符串输出 'aa'
    }
    return res
};

4. 数组的排序?

// 快速排序
<script>
    var arr = [10, 33, 44, 4, 12, 15, 0];
    function quickSort(arr) {
      if (arr.length <= 1) {
        return arr
      }
      var index = Math.floor(arr.length - 1 / 2)
      var val = arr.splice(index,1) // 删除中间值
      var left = []
      var right = []
      for (var i = 0; i <= arr.length - 1; i++) {
        if (arr[i] < val) {
          left.push(arr[i])
        } else {
          right.push(arr[i])
        }
      }
      return quickSort(left).concat(val, quickSort(right))
    }
    console.log(quickSort(arr)) // [0, 4, 10, 12, 15, 33, 44]
</script>
  
// 冒泡排序
<script>
    var arr = [10, 33, 44, 4, 12, 15, 0];
    function sort(arr) { // 每相邻的两个元素比较,大的沉底
      for (var i = 0; i < arr.length - 1; i++) { // 控制比较的次数
        for (var j = 0; j < arr.length - 1 - i; j++) {
          if (arr[j] > arr[j + 1]) {
            var temp = arr[j]
            arr[j] = arr[j + 1]
            arr[j + 1] = temp
          }
        }
      }
      return arr
    }
    console.log(sort(arr)) // [0, 4, 10, 12, 15, 33, 44]
</script>
  
// 选择排序
<script>
    var arr = [10, 33, 44, 4, 12, 15, 0];
    function sort(arr) { // 每一个元素和后面的所有元素比较,小的元素上浮
      for (var i = 0; i < arr.length - 1; i++) {
        for (var j =  i + 1; j < arr.length - 1; j++) {
          if (arr[i] > arr[j]) {
            var temp = arr[j]
            arr[j] = arr[i]
            arr[i] = temp
          }
        }
      }
      return arr
    }
    console.log(sort(arr)) // [0, 4, 10, 12, 15, 33, 44]
</script>

5. 找出给定字符串中出现次数最多的字符?

  <script>
    var str = "abcdabbcdcc"
    
    // 方法一:
    function getMax(str) {
      var maxStr = ''
      var maxCount = 0
      for (var i = 0; i < str.length; i++) {
        var s = str.charAt(i)
        var count = 0
        for (var j = 0; j < str.length; j++) {
          if (s === str.charAt(j)) {
            count += 1
          }
        }
        if (count > maxCount) {
          maxCount = count
          maxStr = s
        }
      }
      return maxStr
    }

	// 方法二:
    function getMax(str) {
      if (str.length <= 1) {
        return str
      }
      var obj = {}
      for (var i = 0; i < str.length; i++) {
        if (!obj[str.charAt(i)]) { // 为每个字符初始化
          obj[str.charAt(i)] = 1
        } else { // 对已存在的字符值加一
          obj[str.charAt(i)] += 1
        }
      }
      var maxCount = obj[str.charAt(0)]
      var maxStr = str.charAt(0)
      for (var key in obj) {
        if (obj[key] > maxCount) {
          maxCount = obj[key]
          maxStr = key
        }
      }
      return maxStr
    }
    
    console.log(getMax(str)) // "c"
  </script>

6. JS实现斐波那契数列?

数列:1,1,2,3,5,8,13,21…
给定f(1) = 1, f(2) = 1,之后每项值等于前两项之和,求f(n)?

<script>
	// 方法一:递归
    function f(n) {
      if (n === 1 || n === 2) {
        return 1
      } else {
        return f(n - 1) + f(n - 2)
      }
    }

	// 方法二:
    function f(n) {
      var n1 = 1
      var n2 = 1
      for (var i = 0; i < n - 2; i++) {
        var res = n1 + n2
        n1 = n2
        n2 = res
      }
      return res
    }
    
    console.log(f(8)) // 21
</script>

7. 给定一个数,求其阶乘?

<script>
	// 方法一:递归
    function f(n) {
      if (n === 1) {
        return 1
      } else {
        return n * f(n - 1)
      }
    }

	// 方法二:
    function f(n) {
      var res = 1
      for (var i = n; i >= 1; i--) {
        res = res * i
      }
      return res
    }
    
    console.log(f(5)) // 120
</script>

8. 求一个数组中最大值和最小值之差?

var arr = [10, 5, 11, 7, 8, 9]
var max = Math.max(...arr) // 或使用Math.max.apply(null, arr)
var min = Math.min(...arr)
console.log(max - min) // 6

附:apply方法中传入null或undefined时执行的JS对象是window对象。

9. 判断一个字符串在另一个字符串中的位置(不使用字符串的任何方法)?

<script> 
    // 方法一:
    function getIndex(val, str) {
      var reg = new RegExp(val)
      if (str.match(reg)) {
        return str.match(reg).index
      }
    }
    // match方法返回一个数组,数组具有input和index两个属性,input为匹配的原字符串,index为匹配的索引值
    
    // 方法二:
    function getIndex(val, str) {
      for (var i = 0; i < str.length; i++) {
        if (val[0] === str[i]) {
          for (var j = 0; j < val.length; j++) {
            if (val[j] !== str[i + j]) { // str[i + j]可能越界(不影响),返回undefined
              break;
            }
            if (j === val.length - 1) {
              return i
            }
          }
        }
      }
      return -1
    }

    console.log(getIndex("ab", "ghfeabfkhab")) //4
</script>

10. JavaScript实现数组的快速排序?

/**
快速排序思路:
1. 定义初始start和end,i和j,start为数组首位,end为数组末位,i初始化为数组首位,j初始化为数组末位。
2. 将arr[start]作为比较的基数,定义key=arr[start],从右向左找比key大的数,满足则j--,不满足时说明arr[j] < key,保证互换位置后key右侧的值均大于key。
3.同理,从左向右找比key小的数,满足则i++,不满足时说明arr[i] > key,保证互换位置后key左侧的值均小于key。
4.对当前key左侧和右侧的数据分别重复上述过程。
*/

var arr = [12, 11, 13, 4, 5, 7, 18, 33, 99]
function quickSort(arr, start, end) {
  var i = start
  var j = end
  var key = arr[start]
  while(i < j) {
    while(i < j && arr[j] >= key) {
      j--
    }
    if (arr[j] <= key) {
      var temp = arr[j]
      arr[j] = arr[i]
      arr[i] = temp
    }
    while(i < j && arr[i] <= key) {
      i++
    }
    if (arr[i] >= key) {
      var temp = arr[i]
      arr[i] = arr[j]
      arr[j] = temp
    }
  }
  if (i > start) {
    quickSort(arr, start, i - 1)
  }
  if (j < end) {
    quickSort(arr, j + 1, end)
  }
}
quickSort(arr, 0, arr.length - 1)
console.log(arr)

11. 使用快速排序查找数组中位数(奇数)?

<script> 
var arr = [11, 3, 4, 5, 19]
function quickSort(arr, start, end) {
  var i = start
  var j = end
  var key = arr[start]
  if (start < end) {
    while(i < j) {
      while(i < j && arr[j] >= key) {
        j--
      }
      if (arr[j] <= key) {
        var temp = arr[j]
        arr[j] = arr[i]
        arr[i] = temp
      }
      while(i < j && arr[i] <= key) {
        i++
      }
      if (arr[i] >= key) {
        var temp = arr[i]
        arr[i] = arr[j]
        arr[j] = temp
      }
    }
    if (i === (arr.length - 1) / 2) {
      return arr[i]
    } else if (i > (arr.length - 1) / 2) { // 中位数在左侧
      return quickSort(arr, start, i - 1)
    } else { // 中位数在右侧
      return quickSort(arr, j + 1, end)
    }
  } else { // start === end时,如数组中只有一个元素
    return arr[start]
  }  
}
console.log(quickSort(arr, 0, arr.length - 1))
</script> 

12. 求f(2)(3)(4)…的值?

运算规则:res = 2 + 3 + 4 + … (使用柯里化)

详见:https://segmentfault.com/a/1190000008263193

// 方法一:
function add(a){
    var sum = 0;
    sum += a;     
    return function temp(b) {   
        if (arguments.length === 0) {
            return sum;
        } else {
            sum= sum+ b;
            return temp;
        }
    }
}
add(2)(3)(4)(5)(); //14

// 方法二:(匿名函数)
function add() {
  var _args = [];
  return function(){ 
    if(arguments.length === 0) { 
      return _args.reduce(function(a,b) {
        return a + b;
      });
    }
    [].push.apply(_args, [].slice.call(arguments));
    return arguments.callee;
  }
}
var sum = add();
sum(2,3)(4)(5)(); //14
    
// 方法三:
function add(a) {
    var sum = 0;  
        sum += a;     
    var temp = function(b) {
        if(arguments.length===0){
            return sum;
        } else {
            sum = sum+ b;
            return temp;
        }
    }
    temp.toString = temp.valueOf = function() {
        return sum; 
    } 
    return temp;
}
add(2)(3)(4)(5)(); //14

13. 待续。。。?

猜你喜欢

转载自blog.csdn.net/GreyBearChao/article/details/83106757