【笔试】编程题

1. 已知购买礼物的总金额,各礼品的单价-数组A和热度值-数组B,求礼物的最大热度值。(动态规划之01背包问题)

JAVA实现:

public static void solution(int total,int[] prices,int[] hots) {
        int[][] results = new int[prices.length+1][total+1];
        for (int i = 1; i < prices.length+1; i++) {
            for (int j = 1; j < total+1; j++) {
                if (j < prices[i-1]) {
                    results[i][j] = results[i-1][j];
                }else {
                    results[i][j] = Math.max(results[i-1][j],results[i-1][j-prices[i-1]]+hots[i-1]);
                }
            }
        }
        System.out.println(results[prices.length][total]);
}

JS实现:【编程题】动态规划之01背包问题

2. 已知数组 arr 和它的长度 n ,求数组中所有连续 k(1~n)个长度中的最大值中的最小值。(滑动窗口的最大值---拓展题)

假设:输入的数组为 arr = [1,3,2,4,6,5] ,长度为 n = 6。输出需为 n 个数字,第 i 个数字表示 k=i 时的答案。例如:当 k=2 时,连续的数组有 [1,3],[3,2],[2,4],[4,6],[6,5]。先求每组的最大值max,再求这些最大值中的最小值min。故输出中的第二个数字是3。

JS实现:方法一(推荐)

function minInMax(arr,n){
    if(!arr.length || !n){
        return [];
    }

    let res = [];

    for(let size=1; size<n+1; size++){
        res.push(maxInWindows(arr,size));
    }

    return res;
}

function maxInWindows(arr,size){
    let min; // 所有滑动窗口里数值的最大值中的最小值

    let max = []; // 用来保存所有滑动窗口里数值的最大值
    let queue = []; // 用来保存有可能是滑动窗口最大值的数字的下标

    for(let i=0; i<size; i++){
        // 在存入一个数字的下标之前,首先要判断队列里已有数字是否小于待存入的数字。
        // 如果已有数字小于待存入的数字,那么这些数字已经不可能是滑动窗口的最大值,因此它们将会被依次从队列的尾部删除
        while(queue.length && arr[i] > arr[queue[queue.length-1]]){
            queue.pop();
        }
        queue.push(i); // 每次都存入一个数字的下标
    }

    min = arr[queue[0]]; // 初始化最小值为第一个滑动窗口的最大值

    for(let i=size; i<arr.length; i++){
        max.push(arr[queue[0]]); // 队列头部的数字就是每次滑动窗口的最大值

        // 每次得到一个滑动窗口的最大值都与当前的最小值min相比
        // 如果小于最小值min,就将其赋值给它
        if(arr[queue[0]] < min){ 
            min = arr[queue[0]];
        }

        while(queue.length && arr[i] > arr[queue[queue.length-1]]){
            queue.pop();
        } 

        // 如果队列头部的数字已经从窗口滑出,那么滑出的数字也需要从队列的头部删除。
        // 队列头部的数字从窗口滑出的条件:即将保存的数字的下标 - 队列头部保存的下标 >= 滑动窗口的大小。
        if(queue.length && queue[0] <= i-size){
            queue.shift();
        }       
        queue.push(i);
    }
    max.push(arr[queue[0]]); // 加入最后一个滑动窗口的最大值

    if(arr[queue[0]] < min){ // 比较最后一次
        min = arr[queue[0]];
    }

    return min;
}

// 测试
let arr = [1,3,2,4,6,5];
let n = 6;
console.log(minInMax(arr,n)); // [ 1, 3, 3, 4, 6, 6 ]

JS实现:方法二

function choose(arr){
    if(!arr.length){
        return [];
    }

    let n = arr.length;  // 数组的长度
    let res = []; // 用来保存结果

    res[0] = Math.min.apply(null,arr); // k=1 时的min
    res[n-1] = Math.max.apply(null,arr); // k=n 时的min

    let k = 2; // k(1~n)表示滑动窗口的大小
    while(k<n){ // k(1~n-1)
        // 初始化最小值为第一个滑动窗口的最大值
        let min = Math.max.apply(null,arr.slice(0,k)); 

        for(let i=1;i<n-k;i++){ // 从第二个滑动窗口开始
            let max = Math.max.apply(null,arr.slice(i,i+k));
            min = Math.min(max,min);
        }

        res[k-1] = min;
        k++;
    }

    return res;
}

// 测试
let arr = [1,3,2,4,6,5];
console.log(choose(arr)); // [ 1, 3, 3, 4, 6, 6 ]

参考:【编程题】滑动窗口的最大值

3. 求两个字符串的最大公共子字符串,如"abccade","dgcadde"的最大子字符串为"cad"。

function findSubStr(s1,s2){
    let str="",L1=s1.length,L2=s2.length;
    // 将短字符串赋值给s1,长字符串赋值给s2
    if (L1>L2){ 
        let s3=s1;
        s1=s2;
        s2=s3;
        L1=s1.length;
        L2=s2.length;
    }  
    for (let j=L1; j>0; j--){
        let temp;
        for (let i=0; i<j; i++){ 
            temp = s1.substr(i,j); 
            if (s2.indexOf(temp)>=0) break;  
        } 
        if(temp.length>str.length){
            str = temp;
        }       
    }  
    return str;  
}
// 测试
const str1 = 'abcbbd';
const str2 = 'dcbbdcdabcbb';
let comStr = findSubStr(str1,str2);
console.log(comStr);  // abcbb

4. 交换单向链表中两个节点m,n的位置。

解题思路:定义两个指针p1,p2,先让指针p2走|m-n|步,然后两个指针同时移动,直到分别走到m-1,n-1的位置,最后进行一系列交换即可。

5. 找出数组A中存在,而数组B中不存在的数字。假设每个数组中都没有重复的数字。

解题思路:(哈希表)将数组B中的数字存入哈希表中,遍历循环数组A,如果在哈希表中没有找到匹配的数字,则输出该数字。

function test(arrA,arrB){
    let res = [];
    let hashMap = new Map();
    for(let i=0; i<arrB.length; i++){
        if(!hashMap.get(arrB[i])){
            hashMap.set(arrB[i],true);
        }        
    }
    for(let j=0; j<arrA.length; j++){
        if(!hashMap.get(arrA[j])){
            res.push(arrA[j]);
        }        
    } 
    return res;   
}

let arrA = [1,2,3];
let arrB = [3,4,5];
console.log(test(arrA,arrB));  
// [1,2]

参考:JS数据结构:哈希表

6. 实现一个笛卡尔积函数。(shopee)

//两个笛卡尔积
function twoDscartes (a, b) {
    let ret = [];
    for (let i = 0; i < a.length; i++) {
        for (let j = 0; j < b.length; j++) {
            ret.push(ft(a[i], b[j]));
        }
    }
    return ret;
}
function ft (a, b) {
    if (!(a instanceof Array))
        a = [a];
    let ret = a.slice(0);
    ret.push(b);
    return ret;
}

// 主函数
function discarts() {
    let len = arguments.length;
    if (len === 0)
        return [];
    else if (len === 1)
        return arguments[0];
    else {
        let r = arguments[0];
        for (let i = 1; i < len; i++) {
            r = twoDscartes(r, arguments[i]);
        }
        return r;
    }
}

let result = discarts([1,2],[4,5],[7,8]);
console.log(result);
// [ [ 1, 4, 7 ],[ 1, 4, 8 ],[ 1, 5, 7 ],[ 1, 5, 8 ],[ 2, 4, 7 ],[ 2, 4, 8 ],[ 2, 5, 7 ],[ 2, 5, 8 ] ]

7. 在JS中,将对象数组按多个字段进行升序排序。(shopee)

前提知识:Array.sort(sortby),数组方法的sortby参数可选,sortby是一个回调方法。

  • 回调方法的参数:两个参数,这两个参数是当前比较的两个元素。
  • 回调方法的返回值:大于0时将两个值互换,否则不换。
// 将数组升序
function sortNumber(a,b){
    return a - b
}

let arr = ["10","5","40","25","1000","1"] 
console.log(arr.sort(sortNumber))
// [ '1', '5', '10', '25', '40', '1000' ]
function sortByArr(arr) {
    return function(a, b) {
        for (let i = 0; i < arr.length; i++) {
            let attr = arr[i];
            if (a[attr] !== b[attr]) {
                return a[attr] - b[attr]
            }
        }
   }
}
let jsonStudents = [
    {totalScore:"197", Chinese:"100",math:"97"},
    {totalScore:"196",Chinese:"99", math:"97"},
    {totalScore:"196",Chinese:"99", math:"10"},
    {totalScore:"185", Chinese:"88", math:"97"},
    {totalScore:"196",Chinese:"90", math:"97"},
    {totalScore:"196", Chinese:"96",math:"100"},
]
console.log(jsonStudents.sort( sortByArr(['totalScore','math','Chinese']) ))   
// [ { totalScore: '185', Chinese: '88', math: '97' },
//   { totalScore: '196', Chinese: '99', math: '10' },
//   { totalScore: '196', Chinese: '90', math: '97' },
//   { totalScore: '196', Chinese: '99', math: '97' },
//   { totalScore: '196', Chinese: '96', math: '100' },
//   { totalScore: '197', Chinese: '100', math: '97' } ]

8. 迷宫。(shopee)

下图表示一个迷宫,其中0表示可通过,1表示障碍,请实现一个函数hashPash(map,start,end),该函数用于判断从起点到终点是否有路可达。

其中,map 是一个表示迷宫的二维数组,start,end 为坐标,表示起点和终点。以屏幕往下为坐标第一维的正方向,以屏幕往右为坐标第二维的正方向。

输入描述:起点,如[0,0];终点,如[5,4];迷宫地图,多维数组。

输出描述:输出1表示可达,0表示不可达。如此示例,输出为1。

 \begin{bmatrix} 0& 1& 0& 0& 0 \\ 0& 0& 0& 1& 0 \\ 0& 1& 0& 1& 0 \\ 1& 1& 1& 0& 0 \\ 0& 1& 0& 0& 1 \\ 0& 1& 0& 0& 0 \end{bmatrix}

9. 最优打字策略。(京东)

切换大小写有两种方式。一种是按下 "caps locks",也就是大写锁定键,这样一来,之后的输入模式都会被切换。另外一种是同时按下 shift 和需要打印的字母,可以临时切换大小写(算作按下两个键)。

已知初始状态下,打字模式是小写,现在给出需要打印的字符串(区分大小写),请你计算出最少需按键多少次才能打印出来。

function test (str,n){
    let words = str.split("");
    let count = n;    
    let flag = 0;
    
    for (let i = 0; i < n; i++) {
        if (words[i] > 'Z' && flag === 1) {
            if (i + 1 < n && words[i + 1] > 'Z') {
                flag = 0;
            }
            count++;
        } else if (words[i] < 'a' && flag === 0) {
            if (i + 1 < n && words[i + 1] < 'a') {
                flag = 1;
            }
            count++;
        }
    }

    return count;
}

let str = "AaAAAA";
console.log(test(str,6));

10. 姓名排序。(京东)

开学季,老师要录入一个拼音版的学生名单。老师录入时,需要输入姓和名(例如:ZAHNG SAN,字母均为大写,姓名以空格隔开),并要将这些人按照一定的规则排序。

排序方式如下:

首先,按照该姓的出现次数排序,即:姓出现次数多的人先排序;

其次,若两个人的姓出现的次数一样多(或者是同一个姓),按照原名单的顺序。

输入描述:原名单,输入多行,每行两个字符串,代表一个人的姓和名。

输出描述:输出排序后的名单。

示例:

输入:['ZHANG SAN', 'LI SI', 'WANG WU', 'WANG LIU', 'WANG QI', 'ZHANG WU', 'LI WU']

输出:['WANG WU', 'WANG LIU', 'WANG QI', 'ZHANG SAN', 'LI SI', 'ZHANG WU', 'LI WU']

参考:https://www.nowcoder.com/discuss/232731?type=post&order=time&pos=&page=0

11. 项目分配。(滴滴)

某公司有N名员工,每名员工可以负责多个项目,但是每个项目只能由一名员工负责。现有M个项目,令 A[i][j] (N行M列)表示第 i 名员工负责第 j 个项目的收益,求最大收益。

解题思路:即求每列的最大值。

function test(n,m,arr){
    let sum = 0;
    for(let i=0; i<m; i++){
        let temp = arr[0][i];
        for(let j=1; j<n; j++){
            if(arr[j][i] > temp){
                temp = arr[j][i];
            }
        }
        sum += temp;
    }
    return sum;
}

let arr = [
    [1,3,3],
    [2,2,2],
    [3,2,1],
];
console.log(test(3,3,arr)); 
// 9

12. 算式转移。(滴滴)

给出一个仅包含加减乘除四种运算的算式(不含括号),如1+2*3/4,在保持运算符顺序不变的情况下,现在你可以进行若干次如下操作:如果交换相邻的两个数,表达式值不变,那么你可以交换这两个数。

现在你可以进行任意次操作,使得算式的数字序列字典序最小,然后输出结果,数字之间的字典序定义为:若a<b,则a的字典序小于b。

输入描述:第一行包含一个整数n,表示算式的长度,即包含n个数字和n-1个运算符。第二行包含一个含有n个非0整数和n-1个运算符的算式,整数和运算符用空格隔开,运算符包括 “+,-,*,/”,整数的绝对值不超过1000。

输出描述:按要求输出字典序最小的表达式,数字与运算符之间用空格隔开。

示例:

输入:6

3 + 2 + 1 + -4 * -5 + 1

输出:1 + 2 + 3 + -5 * -4 + 1

13. 求数组中所有连续子数组的和的 最大值 并指出其 连续子数组。(新浪)

function sumMax(arr){
    let res = subMax(arr,1);
    for(let i=2; i<=arr.length; i++){
        if(subMax(arr,i)[0]>res[0]){
            res = subMax(arr,i);
        }
    }       
    return res;
}

function subMax(arr,size){
    let max = [];
    let queue = [];
    let tempSum;
    for(let i=0; i<size; i++){
        queue.push(arr[i]);
        max[0] = sum(queue);
        max[1] = queue;
        tempSum = sum(queue);
    }
    for(let i=size; i<arr.length; i++){
        tempSum = tempSum - queue.shift() + arr[i];
        queue.push(arr[i]);
        if(tempSum>max[0]){
            max[0] = tempSum;
            max[1] = queue;
        }
    }
    return max;
}

function sum(arr){
    return arr.reduce((result,item)=>result+item,0);
}

let arr = [-1,1,2,3];
console.log(sumMax(arr)); // [ 6, [ 1, 2, 3 ] ]

14. 数组去重,并降序排列——最优。(新浪)

数组去重的多种方法,详见:https://blog.csdn.net/Dora_5537/article/details/100547316

function unique(arr) {
    let res = [...new Set(arr)];
    return res.sort((a,b)=>b-a);
}

let arr = [1,1,4,3,4,5];
let newArr = unique(arr);
console.log(newArr); 

15. 求字符串中所有子串出现次数最多的子串,输出该子串及其出现的次数。(360正式批)

解题思路:求解出现次数最多的单个字符。

function test(str){
    let arr = str.split("");
    let hashMap = new Map();
    let max = [0,0];
    if(arr.length !== 0){
        for(let i=0; i<arr.length; i++){
            if(hashMap.get(arr[i])){
                hashMap.set(arr[i], hashMap.get(arr[i])+1);
            } else {
                hashMap.set(arr[i], 1);
            }
            if(hashMap.get(arr[i]) > max[1]){
                max[1] = hashMap.get(arr[i]);
                max[0] = arr[i];
            }
        }
    }
    return max;
}

let str = 'abcaba';
console.log(test(str)); // [ 'a', 3 ]

16. 散步。(360正式批) 

现有一笔直的道路,包括起点和终点共设有N个结点,将其划分成N-1个等距的部分。小A饭后散步,并不知道自己初始位置在哪,但是他每隔一段时间会用手机看一下自己走了多远,记作D。小A还不记得自己是朝哪个方向走的,唯一可以确定的是,在两次看手机的间隔他不会改变方向,每次看完手机他可能向前或者回头走。

已知他在散步过程中始终在N-1的范围内,那么符合上述条件的终点可能有多少个呢?

输入描述:N,M(表示D的数量),D

输出描述:一个整数,表示终点的数量

示例:

输入:N=10,M=3,D=[5,2,6]

输出:8

let line = read_line();
let lines = line.split(" ");
let n = lines[0];
let m = lines[1];
let arr = [];
for(let i=0; i<m;i++){
    let input = readInt();
    arr.push(input);
}
let count = 0;
getLine(arr,0,0,0,n-1);
print(count);
function getLine(lines,start,maxEnd,lineNumber,maxPointNum) {
    if (start > maxPointNum || start < 0) {        
        return;
    }
    if (lineNumber >= lines.length) {        
        count += maxPointNum - maxEnd + 1;
        return;
    }
    getLine(lines,start+lines[lineNumber],Math.max(maxEnd,start+lines[lineNumber]),lineNumber+1,maxPointNum);
    getLine(lines,start-lines[lineNumber],Math.max(maxEnd,start-lines[lineNumber]),lineNumber+1,maxPointNum);
}

17. 宝箱匹配钥匙。(腾讯)

现有 n 个宝箱和 m 个钥匙,第 i 个宝箱上写有一个整数 ai,第 j 个钥匙上写有一个整数 bj。只有 ai 与 bj 之和为奇数时,钥匙才能打开宝箱。还有,每个宝箱只能被打开一次,每把钥匙只能使用一次。求最多能打开多少宝箱。

输入描述:n,m,a,b,其中 n,m 是整数,a,b 是数组

输出描述:一个整数,表示能打开宝箱的数量

示例:

输入:n=2,m=2,a=[1,1],b=[1,1]

输出:0

function mainTest(boxArr,keyArr) {
    let sta1=test(boxArr);
    let sta2=test(keyArr);
    let ret=Math.min(sta1[0], sta2[1])+Math.min(sta1[1], sta2[0]);
    return ret;
}

function test(nums) {
    let sta=[0,0]; // 存储奇数,偶数的个数
    for(let i=0;i<nums.length;i++){
        if((nums[i]&1)===1){ // 判断奇数
            sta[0]+=1;
        }else{
            sta[1]+=1;
        }
    }
    return sta;
}

let boxArr = [1,2];
let keyArr = [1,2];
let res = mainTest(boxArr,keyArr);
console.log(res); // 2

18. 顾客满意度。(腾讯)

现有 n 个顾客排队,从1到 n 标号。一开始,每个顾客 i 在队伍当中的位置是 i。每个顾客有两个属性 ai 和 bi。每个顾客的不满意度等于站在他前面的人*ai,加上站在他后面的人*bi。假设顾客 i 位于位置 j,那么他的不满意度等于ai*(j-1)+bi*(n-j)。请问如何调整顾客位置,让所有顾客的不满意度总和最小。

输入描述:顾客总数 n,所有顾客的两个属性,为一个二维数组

输出描述:一个整数,表示所有顾客的不满意度总和

示例1:

输入:n=2,所有顾客的两个属性=[[1,1],[2,2]]

输出:3

示例2:

输入:n=3,所有顾客的两个属性=[[1,3],[1,1],[4,1]]

输出:6

解题思路:第一列属性降序排列,若相同,则将第二列属性升序排列。

function satisfaction(arr){
    let newArr = arr.sort(demo);
    let res = 0;
    for(let i=1; i<newArr.length+1; i++){
        res = res + newArr[i-1][0]*(i-1) + newArr[i-1][1]*(newArr.length-i);
    }
    return res; 
}

function demo(a,b){
    if(a[0]===b[0]){
        return a[1]-b[1];
    }
    return b[0]-a[0];
}

let arr = [[1,3],[1,1],[4,1]];
console.log(satisfaction(arr)); // 6

19. 市场竞价。(腾讯)

在一次拍卖会上,有 n 个公司进行拍卖。每次竞价请求以竞拍公司的编号和竞拍价格给出,保证竞拍价格严格递增,拍卖不能一个人连续拍卖两次。

由于一些原因,现在每次要去掉一些竞拍公司的竞拍请求,由于公司太多,于是老板想让你写一个程序帮忙判断每次去掉一些公司后的 winner 和最小拍卖价格。

特别的是,如果去掉一些公司之后有一家公司连续两次竞拍请求,则取最小的价格(但要使得他依然能竞价成功)。

输入描述:竞拍次数 n,每次竞拍的竞拍公司和竞拍价格(长度为 n 的二位数组),询问数q,每次询问要去掉的公司数量及公司编号(长度为 q 的二位数组)。

输出描述:长度为 q 的数组,每个元素有两个数,分别表示第 q 次询问最后竞拍的公司和价格,如果所有公司都被去除则输出[0,0]。

示例:

输入:n=2,[[1,1],[2,2]],q=3,[[1,1],[1,2],[2,1,2]]

输出:[[2,2],[1,1],[0,0]]

function price(n,nArr,q,qArr){
    let res = [];
    for(let i=0; i<q; i++){
        let deNumber = qArr[i][0];
        if(deNumber>=n){
            res.push([0,0]);
        } else {
            let t = n-1;
            for(let j=1; j<qArr[i].length; j++){
                if(nArr[t][0] !== qArr[i][j]){
                    continue;
                }
                t--;
            }
            res.push(nArr[t]);
        }
    }
    return res; 
}

let n = 2;
let nArr = [[1,1],[2,2]];
let q = 3;
let qArr = [[1,1],[1,2],[2,1,2]];
console.log(price(n,nArr,q,qArr)); // [[2,2],[1,1],[0,0]]

20. 判断某一年的2月有多少天,即判断每年是平年还是闰年。(腾讯)

闰年的判断条件:(1)年份能被4整除,且不能被100整除;(2)年份能被400整除。

function test(year){
    if( year%4 === 0 && year%100 !== 0 || year%400 === 0) return 29;
    return 28;
}

let res = test(2007);
console.log(res); // 28

21. 判断1~n 的所有整数中,有多少个1?

function NumberOf1Between1AndN_Solution(n){
    let sum = 0;
    for (let i = 1; i<=n ;i++){
        sum+= getNumsFromStr(i.toString(), '1')
    }
    console.log(sum); // 4个1
    return sum;
};

function getNumsFromStr(str, char){
    let ret = 0;
    str.split('').forEach(c => {
        if(c === char) ret ++
    });
    return ret;
};

NumberOf1Between1AndN_Solution(11);

22. 现有许多不同身高的机器人在一条直线上排队,按顺序站成一排,排头向前,并且其他机器人均朝向排头一个方向,每个机器人都有一双只能看向正前方的眼睛,不能往斜上或斜下方向看;一般来说,如果前面有比自己高或者一样高的机器人,机器人可以看到它;举例:6,5,3,4,身高为4的机器人只能看到身高为5的机器人;4,5,6,7,这种情况,每个机器人都看不到前面的机器人。请问,能被看到最多的机器人是哪个?

输入:机器人的个数 n,表示身高的数组 arr。

输出:满足要求的机器人的身高。

示例:输入:4,[6,5,3,4];输出:5。

function test(arr,n){
    let hashMap = new Map();
    let res = [0,0];
    for(let i=n-1; i>0; i--){
        for(let j=i-1; j>=0; j--){
            if(arr[j]>=arr[i]){
                if(!hashMap.get(arr[j])){
                    hashMap.set(arr[j],1);
                } else {
                    hashMap.set(arr[j],hashMap.get(arr[j])+1);
                }  
                if(res[0]<hashMap.get(arr[j])){
                    res[0] = hashMap.get(arr[j]);
                    res[1] = arr[j];
                }              
                break;
            }
        }
    }
    return res[1];
}

23. 小Q制作了一个简单的游戏:有一排方块每个方块是一个自然数或'<'或'>'。小Q一开始在最左边的方块上,且方向向右。若小Q在数字方块上,他会得到方块上数字对应的分数,并且方块上的数字会减一。特别地,当小Q走在数字为0的方块时,它会得到分数0,然后摧毁这个方块,方块数量减一。当小Q在 '<'或'>'方块上时,他会改变接下来的前进方向,分别代表向左、向右。特别地,他也会摧毁这个方块。当小Q走出这排方块时,游戏结束。请计算他得到的分数。

输入:方块数量 n,方块数组 arr,游戏区间 start(最小为1)、end(最大为 arr.length)。

输出:分数。

示例:输入:4,['>',2,2,'<'],[1,4],[1,3],[2,4],[2,3],[1,1],[2,2];输出:6,4,6,4,0,2。

function test(arr,n,start,end){
    let count = 0;
    let i = start-1;
    let boolean = true;
    let t = end;
    while(i>=start-1 && i<t && t<=arr.length){
        if(arr[i] === '>'){
            arr.splice(i,1);
            t--;
            boolean = true;            
            continue;
        }
        if(arr[i] === '<'){
            arr.splice(i,1);
            t--;
            i--;
            boolean = false;
            continue;
        }
        count = count + arr[i];
        arr[i] = arr[i]-1;
        if(arr[i]===0){
            arr.splice(i,1);
            t--;
            i = boolean ? i : i-1;
        } else {
            i = boolean ? i+1 : i-1;
        }          
    }
    return count;        
}

let arr = ['>',2,2,'<'];
console.log(test(arr,4,1,3)); // 4

24. 给定一个数组,它的第i个元素是一支给定股票第i天的价格。如果你只允许完成一笔交易(即买入和卖出一支股票),求最大利润。注意:你不能在买入股票之前卖出股票。

示例1:输入:[7,1,5,3,6,4],输出:5

示例2:输入:[7,6,4,3,1],输出:0

function maxProfit(prices) {
    let buy = prices[0];
    let sell; 
    let max = 0;
    for (let i = 1; i < prices.length; i++) {
        if (prices[i] > buy) {
            sell = prices[i];
            max = Math.max(max, sell - buy);
        } else {
            buy = prices[i];
        }
    }
    return max;
}

25. 逆时针打印nXm矩阵。(猿辅导)

// n 行 m 列
function test(n,m,arr){
    let result = [];
    let start = 0;
    while(n>start*2 && m>start*2){
        let endX = m - 1 - start;
        let endY = n - 1 - start;
        // 从上往下
        for(let i=start; i<=endY; i++){
            result.push(arr[i][start]);
        }
        // 从左往右
        if(start < endX){
            for(let i=start+1; i<=endX; i++){
                result.push(arr[endY][i]);
            }
        }
        // 从下往上
        if(start<endX && start<endY){
            for(let i= endY-1; i>=start; i--){
                result.push(arr[i][endX]);
            }       
        }
        // 从右往左
        if(start<endX && start<endY){
            for(let i= endX-1; i>=start+1; i--){
                result.push(arr[start][i]);
            }       
        }
        start++;
    }
    return result;
}

// let arr = [[1],[2],[3]];
// console.log(test(3,1,arr));

// let arr = [[1,2],[3,4],[5,6]];
// console.log(test(3,2,arr));

// let arr = [[1,2,3,4],[5,6,7,8],[9,10,11,12]];
// console.log(test(3,4,arr));

// let arr = [[1,2,3,4,5,6],[7,8,9,10,11,12]];
// console.log(test(2,6,arr));

let arr = [[1,2,3,4,5],[6,7,8,9,10],[11,12,13,14,15],[16,17,18,19,20]];
console.log(test(4,5,arr));
// [ 1, 6, 11, 16, 17, 18, 19, 20, 15, 10, 5, 4, 3, 2, 7, 12, 13, 14, 9, 8 ]

26. 题目如图所示:(AC9%)

let S = 'ababac';
let T = 'ab';
for(let i=1;i<=S.length;i++){
    let temp = S.substring(0,i);
    if(temp.length<T.length){
        console.log(0);
    } else {
        if(temp.indexOf(T)<0){
            console.log(0);
        } else {
            let count = 0;
            for(let i=temp.indexOf(T); i<=temp.lastIndexOf(T); i++){
                let t = temp.substring(i,i+T.length);
                if(t===T) count++;
            }
            console.log(count);
        }
    }
}
// 0 1 1 2 2 2

27. 题目如图所示:(AC0,题目示例有问题,还是我理解错了?)

let n = 2;
let m = 4;
let arr = [1,2,3,4];
let lines = [[1,4],[3,4],[1,3],[1,3]];
for(let i=0; i<arr.length; i++){
    let v = 0;
    let a = lines[i][0];
    let b = lines[i][1];
    arr[a]=b;
    let j=0;
    let newA = arr;
    while(j<n){
        let arr1 = [];
        let arr2 = [];
        for(let w=0; w<newA.length-1; w=w+2){
            arr1.push(newA[w]|newA[w+1]);            
        }
        j++;
        for(let k=0; k<arr1.length; k=k+2){
            arr2.push(arr1[k]^arr1[k+1]);            
        }
        j++;
        newA = arr2;
        if(newA.length===1){
            v=newA[0];
            break;
        }        
    }
    console.log(v);
}
// 2
// 2
// 4
// 4

28. 若正整数各位数字之和是x,则这个正整数的最小值n是多少?(网易 AC60%)

举例:因为527是58个9和1个5的和,所以这个正整数的最小值是5后面加58个9。

function test(x){
    if(x<10) return x;
    let n = 0;
    let a = Math.floor(x/9); // Math.floor 向下取整
    let b = x%9;
    let str = '';
    if(b!==0){ str += b.toString();}   
    for(let j=0; j<a; j++){
        str +='9';
    }
    n = Number(str);
    return n;
}
console.log(test(13)); // 49
console.log(test(18)); // 99
console.log(test(3)); // 3
console.log(test(7)); // 7

29. 热门城市排序(马蜂窝 AC50%)

function test(arr){
    // 数组去重
    let line = Array.from(new Set(arr));
    let hashMap = new Map();
    for(let i=0; i<line.length; i++){
        let temp = line[i].split('-');
        if(hashMap.has(temp[1])){
            hashMap.set(temp[1],hashMap.get(temp[1])+1);
        } else {
            hashMap.set(temp[1],1);
        }
    }
    let newArr = [...hashMap.entries()];
    newArr.sort(function(a,b){
        if(a[1]<b[1]){
            return b[1]-a[1];
        }
        if(a[1]===b[1]){
            return a[0].localeCompare(b[0]);
        }
    })
    return newArr;
}

let arr = ['1-beijing','2-shanghai','2-shanghai','3-guilin','3-guilin','4-shanghai'];
console.log(test(arr));
// [ [ 'shanghai', 2 ], [ 'beijing', 1 ], [ 'guilin', 1 ] ]

30.(华为 AC100%)

示例:

输入:n: abcdefgABCDEFG()0123456789,m:BCDEF

输出:abcdefgA*****G()0123456789

let line1 = readline().split(" ");
let str = line1[0];
let target = line1[1];
let n = target.length;
let rep = '';
if(str.indexOf(target)!=-1){
    for(let i=0;i<n;i++){
        rep+='*';
    }
    str = str.replace(new RegExp(target),rep);
}
print(str);

31.(华为 AC20%)

输入:1 3 2(初始能力值为0,之前每有一次值比当前值小,则能力值加1,大,则减1,相等,则不变)

输出:1 1(最大能力值及最终能力值)

let t = parseInt(readline());
for(let i=0; i<t; i++){
    let n = parseInt(readline());
    let line = readline().split(" ");
    let arr = [];
    for(let k=0; k<n; k++){
        arr.push(parseInt(line[k]));
    }
    let power = [0];
    for(let i=1; i<n; i++){
        let add = 0;
        for(let j=0; j<i; j++){
            if(arr[j]<arr[i]){
               add++;
            } else if(arr[j]>arr[i]){
               add--;
            }
        }
        power.push(power[i-1]+add);
    }
    print(Math.max(...power)+" "+power[power.length-1]);
}

// 或者
let t = parseInt(readline());
for(let i=0; i<t; i++){
    let n = parseInt(readline());
    let line = readline().split(" ");
    let arr = [];
    for(let k=0; k<n; k++){
        arr.push(parseInt(line[k]));
    }
    let max = Math.max.apply(null,arr);
    let index = arr.lastIndexOf(max);
    let dp = Array(arr.length);
    dp[0]=0;
    for(let i=1; i<arr.length; i++){
        dp[i] = dp[i-1]+count(arr,i);
    }
    let res = [dp[index],dp[arr.length-1]];
    print(res.join(" "));
}
function count(arr,i){
    let num=0;
    for(let j=0;j<i;j++){
        if(arr[j]<arr[i]){
            num++;
        }else if(arr[j]>arr[i]){
            num--;
        }
    }
    return num;
}

END

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值