首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >刷题:剑指offer第四期(33-44)

刷题:剑指offer第四期(33-44)

作者头像
前端迷
发布2020-02-19 16:45:27
3450
发布2020-02-19 16:45:27
举报
文章被收录于专栏:前端迷前端迷

作者:faremax| 来源:牛客网

https://www.nowcoder.com/discuss/49349

33.把只包含因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含因子7。习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。

function GetUglyNumber_Solution(index) {
    if (index === 0) return 0;
    var uglyNum = [1];
    var factor2 = 0, factor3 = 0, factor5 = 0;
    for (var i = 1; i < index; i++) {
        uglyNum[i] = Math.min(uglyNum[factor2] * 2, uglyNum[factor3] * 3, uglyNum[factor5] * 5);
        if (uglyNum[i] === uglyNum[factor2] * 2) factor2++;
        if (uglyNum[i] === uglyNum[factor3] * 3) factor3++;
        if (uglyNum[i] === uglyNum[factor5] * 5) factor5++;
    }
    return uglyNum[index - 1];
}

34.在一个字符串(1<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置

function FirstNotRepeatingChar(str){
    if(!str || !str.length){
        return -1;
    }
    var hash = {};
    var tempArr = str.split('');
    var unique = [];
    var len = str.length, temp;
    for(var i = 0; i < len; i++){
        temp = tempArr[i];
        if(hash[temp]){
            hash[temp].push(i);
        } else {
            hash[temp] = [i];
        }
    }
    for(var key in hash){
        if(hash.hasOwnProperty(key)){
            if(hash[key].length === 1){
                unique.push(hash[key].pop());
            }
        }
    }
    return Math.min.apply(null, unique);
}

35.在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。即输出P%1000000007

由于时间空间复杂度的限制,js 貌似无法完成这个题,所以使用 c++ 完成。

class Solution {
public:
    long long InversePairsCore(vector &data, vector&copy, int start, int end){
        if(start == end){
            copy[start] = data[start];
            return 0;
        }
        int length = (end - start) / 2;
        long long left = InversePairsCore(copy, data, start, start + length);
        long long right = InversePairsCore(copy, data, start + length + 1, end);
        int i = start + length;
        int j = end;
        int indexCopy = end;
        long long count=0;
        while(i >= start && j >= start + length + 1){
            if(data[i] > data[j]){
                copy[indexCopy--] = data[i--];
                count += j - start - length;
            } else {
                copy[indexCopy--] = data[j--];
            }
        }
        for(; i >= start; --i)
            copy[indexCopy--] = data[i];
        for(;j >= start + length + 1; --j)
            copy[indexCopy--] = data[j];
        return left + right + count;
    }
    int InversePairs(vector data) {
        int length = data.size();
        if(length <= 0)
            return 0;
        vector copy;
        for(int i = 0; i < length; i++)
            copy.push_back(data[i]);
        long long count = InversePairsCore(data, copy, 0, length-1);
        copy.clear();
        return count % 1000000007;
    }
};

36.输入两个链表,找出它们的第一个公共结点。

function FindFirstCommonNode(pHead1, pHead2){
    if(!pHead1 || !pHead2){
        return null;
    }
    var len1 = getLength(pHead1);
    var len2 = getLength(pHead2);
    var lenDiff = len1 - len2;
    var curr1 = pHead1;
    var curr2 = pHead2;
    if(len2 > len1){
        curr1 = pHead2;
        curr2 = pHead1;
        lenDiff = len2 - len1;
    }
    for(var i = 0; i < lenDiff; ++i)
        curr1 = curr1.next;
    while(curr1 && curr2 && curr1 != curr2){
        curr1 = curr1.next;
        curr2 = curr2.next;
    }
    return curr1;
    function getLength(node){
        var len = 0;
        curr = node;
        while(curr){
            len++;
            curr = curr.next;
        }
        return len;
    }
}

37.统计一个数字在排序数组中出现的次数。

function GetNumberOfK(data, k){
    return data.reduce(function(count, a){
        return a === k ? count+1 :count;
    }, 0);
}

38.输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。

function TreeDepth(pRoot){
    if(!pRoot){
        return 0;
    }
    var depth = 0;
    var currDepth = 0;
    dfs(pRoot);
    return depth;
    function dfs(node){
        if(!node){
            depth = depth > currDepth ? depth : currDepth;
            return;
        }
        currDepth++;
        dfs(node.left);
        dfs(node.right);
        currDepth--;
    }
}

39.输入一棵二叉树,判断该二叉树是否是平衡二叉树。

function IsBalanced_Solution(pRoot){
    if(!pRoot){
        return true;
    }
    var left = TreeDepth(pRoot.left);
    var right = TreeDepth(pRoot.right);
    var diff = left - right;
    if(diff > 1 || diff < -1)
        return false;
    return IsBalanced_Solution(pRoot.left) && IsBalanced_Solution(pRoot.right);
    function TreeDepth(pRoot){
        if(!pRoot){
            return 0;
        }
        var depth = 0;
        var currDepth = 0;
        dfs(pRoot);
        return depth;
        function dfs(node){
            if(!node){
                depth = depth > currDepth ? depth : currDepth;
                return;
            }
            currDepth++;
            dfs(node.left);
            dfs(node.right);
            currDepth--;
        }
    }
}

40.一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。

function FindNumsAppearOnce(array){
    if (!array || array.length < 2)
        return [];
    return array.sort().join(',').replace(/(\d+),\1/g,"").replace(/,+/g,',').replace(/^,|,$/, '').split(',').map(Number);
}

41.小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100。但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数)。没多久,他就得到另一组连续正数和为100的序列:18,19,20,21,22。现在把问题交给你,你能不能也很快的找出所有和为S的连续正数序列? Good Luck!

function FindContinuousSequence(sum){
    if(sum < 3){
        return [];
    }
    var small = 1, big = 2;
    var mid = (1 + sum) / 2;
    var curr = small + big;
    var result = [];
    while(small < mid){
        if(curr === sum){
            pushSeq(small, big);
        }
        while(curr > sum && small < mid){
            curr -= small;
            small++;
            if(curr === sum){
                pushSeq(small, big);
            }
        }
        big++;
        curr += big;
    }
    result.sort(function(a,b){return a[0] - b[0];});
    return result;
    function pushSeq(small, big){
        var temp = [];
        for(var i = small; i <= big; i++){
            temp.push(i);
        }
        result.push(temp);
    }
}

42.输入一个递增排序的数组和一个数字S,在数组中查找两个数,是的他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。

function FindNumbersWithSum(array, sum){
    if(!array || !array.length){
        return [];
    }
    var result = [];
    var product = [];
    var head = 0, tail = array.length - 1;
    while(head < tail){
        var curr = array[head] + array[tail];
        if(curr === sum){
            result.push([array[head], array[tail]]);
            product.push(array[head] * array[tail]);
            tail--;
            head++;
        } else if(curr > sum){
            tail--;
        } else {
            head++;
        }
    }
    if(result.length === 0){
        return [];
    }
    var min = Math.min.apply(null, product);
    var index = product.indexOf(min);
    return result[index];
}

43.汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果。对于一个给定的字符序列S,请你把其循环左移K位后的序列输出。例如,字符序列S=”abcXYZdef”,要求输出循环左移3位后的结果,即“XYZdefabc”。是不是很简单?OK,搞定它!

function LeftRotateString(str, n){
    if(!str){
        return "";
    }
    var len = str.length;
    n = n % len;
    var left = str.slice(0,n);
    var right = str.slice(n);
    return right + left;
}

44.牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上。同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意思。例如,“student. a am I”。后来才意识到,这家伙原来把句子单词的顺序翻转了,正确的句子应该是“I am a student.”。Cat对一一的翻转这些单词顺序可不在行,你能帮助他么?

function ReverseSentence(str){
    return str.split(' ').reverse().join(' ');
}
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-01-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端迷 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档