[关闭]
@xudongh 2017-10-15T17:04:24.000000Z 字数 1904 阅读 916

几道算法题

算法


1.假设有一个数,这个数的每一位数都不同,且每一位都不能为0,每一位数相加得到s。现在要求输入s,输出这个数的最大值。
即对于某个数s,s=a+b+c+d,其中a≠b≠c≠d≠0,求出abcd的最大值。
如此时程序输入s=9,则输出126。

实现思路:当位数最大时,此值最大;如果位数最大时不满足s=a+b+c+d,则位数减一,寻找满足条件的最大值。
因此,分两步进行,第一步寻找最大位数;
若第一步没有找到满足条件的值,位数减一,继续寻找。

代码实现:

  1. function findNum(s) {
  2. if (s < 1 || s > 42) {
  3. return
  4. }
  5. var numArr = [1];
  6. var bit = 1;
  7. var numPlus = 1;
  8. while (numPlus < s) {
  9. numArr[bit] = ++bit;
  10. numPlus = bit * (1 + bit) / 2;
  11. }
  12. if (numPlus == s) {
  13. return parseInt(numArr.reverse().join(''));
  14. } else if (numPlus > s) {
  15. numArr.pop();
  16. var index = bit - 2;
  17. findNumStep2(index);
  18. return parseInt(numArr.reverse().join(''));
  19. }
  20. function findNumStep2(index) {
  21. var digit = index + 1;
  22. while (sumArr(numArr) !== s) {
  23. numArr[index] = ++digit;
  24. if (digit >= 9) {
  25. break;
  26. }
  27. }
  28. if (sumArr(numArr) !== s) {
  29. findNumStep2(--index);
  30. }
  31. return
  32. }
  33. function sumArr(arr) {
  34. var sum = 0;
  35. for (var i = 0; i < arr.length; i++) {
  36. sum += arr[i];
  37. }
  38. return sum
  39. }
  40. }
  41. // 假设s = 20
  42. findNum(20) // 95321

  1. 寻找既是回文数又是素数的数。
    如12321、1551的数称为回文数。

实现思路:一开始自己写得比较复杂,导致程序内存溢出了。后来优化下,也拆分代码,分别做回文判断和素数判断。
目前用的素数判断是比较粗暴拙劣的方法,在上网查了下关于素数判断的方法,有很多值得学习的算法(如费马小定理),有时间继续深究。

代码实现:

  1. function isPP (min, max) {
  2. let result = []
  3. while (min < max) {
  4. if (isPalindrome(min) && isPrime(min)) {
  5. result.push(min)
  6. }
  7. min++
  8. }
  9. return result
  10. }
  11. function isPalindrome (num) {
  12. let str1 = num.toString()
  13. let str2 = str1.split('').reverse().join('')
  14. if (str1 === str2) {
  15. return true
  16. } else {
  17. return false
  18. }
  19. }
  20. function isPrime (num) {
  21. if (num < 2) return false
  22. if (num !== 2 && num % 2 === 0) return false
  23. let sqrtNum = Math.sqrt(num);
  24. for (let i = 3; i <= sqrtNum; i += 2) {
  25. if (num % i === 0) return false
  26. }
  27. return true
  28. }

3.对于给定字符串如'aaaabbcccd',其字符串价值为字符出现次数的平方和,即为4 * 4 + 2 * 2 + 3 * 3 + 1 * 1。输入字符串和整数k,k为可移除字符串中某一字符的次数。求出最小字符串价值。

实现思路:毫无疑问,被移除的字符一定是出现次数最大的字符。思路是构建二维数组,数组元素为字符和字符出现的次数。然后进行删除字符操作和统计字符串价值。

代码实现:

  1. function strValue (s, k) {
  2. let result = 0
  3. let sArr = [...new Set(s)] // 去重的字符数组
  4. let count = []
  5. // 构建二维数组
  6. for (var i = 0;i < sArr.length; i++) {
  7. let n = s.match(new RegExp(sArr[i], 'g')).length
  8. count[i] = [sArr[i], n];
  9. }
  10. // 二维数组的元素根据出现次数排序
  11. count.sort((a, b) => {
  12. return b[1] - a[1]
  13. })
  14. // 移除出现次数最多的字符,执行k次
  15. while (k--) count.shift()
  16. // 计算价值
  17. for (var j = 0; j < count.length; j++) {
  18. result += Math.pow(count[j][1], 2)
  19. }
  20. return result
  21. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注