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。
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