算法题目总结

202 阅读5分钟

1.给定一个整数数组 A,只有我们可以将其划分为三个和相等的非空部分时才返回 true,否则返回 false。

形式上,如果我们可以找出索引 i+1 < j 且满足 (A[0] + A[1] + ... + A[i] == A[i+1] + A[i+2] + ... + A[j-1] == A[j] + A[j-1] + ... + A[A.length - 1]) 就可以将数组三等分。

示例 1:

输入:[0,2,1,-6,6,-7,9,1,2,0,1]
输出:true
解释:0 + 2 + 1 = -6 + 6 - 7 + 9 + 1 = 2 + 0 + 1

示例 2:

输入:[0,2,1,-6,6,7,9,-1,2,0,1]
输出:false

示例 3:

输入:[3,3,6,5,-2,2,5,1,-9,4]
输出:true
解释:3 + 3 = 6 = 5 - 2 + 2 + 5 + 1 - 9 + 4
  • 解答
var canThreePartsEqualSum = function(A) {
    function getSum(a,b){
        return a+b;
    }
    let sum=A.reduce(getSum,0);
    if(sum%3!==0){
        return false;
    }else{
        let average=0;
        average=sum/3;
        let t='';
        let all1=0;
        let all2=0;
        let index=0;
        console.log(A.length);
        for(let i=0;i<A.length;i++){
            all1+=A[i];
            if(all1===average){
                index=i;
                break;
            }
            if(i===A.lenght){
                return false;
            }
        }
        for(let j=A.length-1;j>index;j--){
            all2+=A[j]
            if(all2===average){
                return true;
            }
            if(j===index+1){
                return false;
            }
        }
    }
    
};

2.编写一个算法来判断一个数是不是“快乐数”。

一个“快乐数”定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1,也可能是无限循环但始终变不到 1。如果可以变为 1,那么这个数就是快乐数。

示例:

输入: 19
输出: true
解释: 
12 + 92 = 82
82 + 22 = 68
62 + 82 = 100
12 + 02 + 02 = 1
  • 解答
var isHappy = function(n) {
   n+='';
    let s=new Set();
   let sum;
    while(sum!==1){
        sum=0;
        for(let i=0;i<n.length;i++){
            sum+=n[i]*n[i];
        }
        if(s.has(sum)){
            return false;
        }
        n=sum+'';
        s.add(sum);
    }
    return true;
}

3.给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点。

输入:
{"$id":"1","next":{"$id":"2","next":null,"random":{"$ref":"2"},"val":2},"random":{"$ref":"2"},"val":1}

解释:
节点 1 的值是 1,它的下一个指针和随机指针都指向节点 2 。
节点 2 的值是 2,它的下一个指针指向 null,随机指针指向它自己。
  • 解答
const copyRandomList = head => {
    if(!head){
        return null;
    }
    let curr=head;
    let node=new Node();
    let tmp=node;
    let map=new Map();
    while(curr){
        tmp.val=curr.val;
        tmp.next=curr.next?new Node():null;
        map.set(curr,tmp);
        tmp=tmp.next;
        curr=curr.next;
    }
    tmp=node;
    while(head){
       tmp.random=head.random?map.get(head.random):null;
        head=head.next;
        tmp=tmp.next;
    }
    return node;
}

4.给定一个只包含数字的字符串,复原它并返回所有可能的 IP 地址格式。

输入: "25525511135"
输出: ["255.255.11.135", "255.255.111.35"]
  • 解答
var restoreIpAddresses = function(s) {
   let result=[];
    let back=function(arr,s){
        if(arr.length===4&&!s){
            result.push(arr.join('.'));
            return ;
        }
        if(!s||arr.length>4){
            return ;
        }
        if(s.slice(0,1)==='0'){
            back(arr.concat(['0']),s.slice(1));
        }else{
            for(let i=1;i<4&&i<=s.length;i++){
                let str=s.slice(0,i);
                if(Number(str)<256){
                    back(arr.concat([str]),s.slice(i))
                }
            }
        }
    }
    back([],s);
    return result;
};

5.翻转一棵二叉树。

示例:

输入

     4
   /   \
  2     7
 / \   / \
1   3 6   9

输出

     4
   /   \
  7     2
 / \   / \
9   6 3   1
  • 解答
var invertTree = function(root) {
    if(!root){
        return root;
    }
    let left=root.left;
    let right=root.right;
    root.left=right;
    root.right=left;
    invertTree(root.left);
    invertTree(root.right);
    return root;
};

6. 合并两个有序链表

将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4
  • 解答
var mergeTwoLists = function(l1, l2) {
    if(!l1){
        return l2;
    }
    if(!l2){
        return l1;
    }
    if(l1.val<l2.val){
        l1.next=mergeTwoLists(l1.next,l2);
        return l1;
    }else{
        l2.next=mergeTwoLists(l2.next,l1);
        return l2;
    }
};

7.数字1的个数

给定一个整数 n,计算所有小于等于 n 的非负整数中数字 1 出现的个数。

输入: 13
输出: 6 
解释: 数字 1 出现在以下数字中: 1, 10, 11, 12, 13 。
  • 解答
var countDigitOne = function(n) {
    let low=0;
    let curr=0;
    let high=0;
    let count=0;
    let per=1;
    if(n<=0){
        return 0;
    }
    while(Math.floor(n/per)!=0){
        curr=Math.floor(n/per)%10;
        low=n-Math.floor(n/per)*per;
        high=Math.floor(n/(per*10));
        switch(curr){
            case 0:
                count+=high*per;
                break;
            case 1:
                count+=high*per+low+1;
                break;
            default:
                count+=(high+1)*per;
                break;
        }
        per=per*10;
    }
    return count;
}

8.动态规划问题

你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。

输入: [1,2,3,1]
输出: 4
解释: 偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。
     偷窃到的最高金额 = 1 + 3 = 4 。

输入: [2,7,9,3,1]
输出: 12
解释: 偷窃 1 号房屋 (金额 = 2), 偷窃 3 号房屋 (金额 = 9),接着偷窃 5 号房屋 (金额 = 1)。
     偷窃到的最高金额 = 2 + 9 + 1 = 12 。
  • 解题
var rob = function(nums) {
    let arr=[];
    arr[0]=0;
    arr[1]=nums[0];
    arr[2]=nums[1];
    if(!nums){
        return 0;
    }
    for(let i=2;i<=nums.length;i++){
        arr[i]=Math.max(arr[i-1],arr[i-2]+nums[i-1]);
    }
    return arr[nums.length];
    
};

9. 合并两个有序数组

给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组。

说明:

初始化 nums1 和 nums2 的元素数量分别为 m 和 n。 你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。 示例:

输入:
nums1 = [1,2,3,0,0,0], m = 3
nums2 = [2,5,6],       n = 3
输出: [1,2,2,3,5,6]
  • 解答:
var merge = function(nums1, m, nums2, n) {
    let len1=m-1;
    let len2=n-1;
    let length=m+n-1;
    while(len1>=0&&len2>=0){
        nums1[length--]=nums1[len1]>=nums2[len2]?nums1[len1--]:nums2[len2--]; 
    }
    function copy(){
        nums1.splice(0,len2+1,...nums2.slice(0,len2+1));
    }
    copy();
};

10.爬楼梯

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

注意:给定 n 是一个正整数。

输入: 2
输出: 2
解释: 有两种方法可以爬到楼顶。
1.  1 阶 + 1 阶
2.  2 阶
输入: 3
输出: 3
解释: 有三种方法可以爬到楼顶。
1.  1 阶 + 1 阶 + 1 阶
2.  1 阶 + 2 阶
3.  2 阶 + 1 阶
  • 解答
var climbStairs = function(n) {
    let curr=[];
    curr[0]=1;
    curr[1]=1;
    for(let i=2;i<=n;i++){
        curr[i]=curr[i-1]+curr[i-2];
    }
    return curr[n];
};

题目来自 leetcode-cn.com/problems/pa…