牛客网刷题总结

提示:


一、NC137 表达式求值

char[] c = s.toCharArray();//字符串转化为数组,里面存放char类型
字符变数字:char c=s.charAt(i);
number=c-‘0’//字符相减为两字符ascll码相减

示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。

二、NC91 最长递增子序列

HashMap<Integer,Integer> map = new HashMap<>();
map.put(1,1)
Integer key = map.getKey()
Integer value = map.getValue()
map.containsKey(1)//键中是否包含这个数据
map.get(1)//通过建拿值
map.isEmpty()//
map.size()
map.remove(1)//从建中删除

Map集合中没有迭代器Iterator,而Set具备迭代器Iterator
Map的遍历有两种方法,一种是keySet(),一种是entrySet()

  • keySet写法1
  Set<String> keys = hashMap.keySet();
  // 获取Set集合的迭代器it
  Iterator<String> it = keys.iterator();
  // 通过迭代器遍历Set集合的每一个元素,也就是存入的键key
  while(it.hasNext()){
      String key = it.next();
      //有了键,就可以通过map集合的get方法获取对应的值
      String value = hashMap.get(key);
      System.out.println(key + "  :  " + value);
  }
  • keySet写法2(常用)
 // 先keySet()取出Map集合的所有键并转成Set集合
 Set<String> keys = hashMap.keySet();
 // 获取Set集合的迭代器it
 Iterator<String> it = keys.iterator();
  • 写法2再简化
Iterator<String> it = hashMap.keySet().iterator();
  • entrySet写法1
// 先entrySet()取出Map集合的所有键值对并存入Set集合
Set< Map.Entry<String,String> > entrySet = hashMap.entrySet();
// 获取Set集合的迭代器it
Iterator< Map.Entry<String,String> > it = entrySet.iterator();
// 通过迭代器遍历Set集合的每一个元素,也就是存入的键值对
while(it.hasNext()){
    Map.Entry<String, String> mey = it.next();
    //getKey()和getValue是接口Map.Entry<K,V>中的方法,getKey()返回对应的键,getValue返回对应的值
    String key = mey.getKey();
    String value = mey.getValue();
    System.out.println(key + "  :  " + value);
}
  • entrySet写法二
 // 先entrySet()取出Map集合的所有键值对并存入Set集合
 Set< Map.Entry<String,String> > entrySet = hashMap.entrySet();
 // 获取Set集合的迭代器it
 Iterator< Map.Entry<String,String> > it = entrySet.iterator();
  • 写法二简化
Iterator< Map.Entry<String,String> > it = hashMap.entrySet().iterator();

定义数组

int[] res = new int[N]//其中N为数组长度

按数值比较的字典序:
比如 123,2,23,213 字典序为:123,2,213,23

三、NC12 重建二叉树

给定节点数为 n 二叉树的前序遍历和中序遍历结果,请重建出该二叉树并返回它的头结点。
输入:
[1,2,4,7,3,5,6,8],[4,7,2,1,5,3,8,6]
返回值:
{1,2,3,4,#,5,6,#,7,#,#,8}

JavaScript slice() 方法
stringObject.slice(start,end)
要抽取的片断的起始下标。如果是负数,则该参数规定的是从字符串的尾部开始算起的位置。也就是说,-1 指字符串的最后一个字符,-2 指倒数第二个字符,以此类推。

JavaScript indexOf() 方法
stringObject.indexOf(searchvalue,fromindex)
该方法将从头到尾地检索字符串 stringObject,看它是否含有子串 searchvalue。开始检索的位置在字符串的 fromindex 处或字符串的开头(没有指定 fromindex 时)。如果找到一个 searchvalue,则返回 searchvalue 的第一次出现的位置。stringObject 中的字符位置是从 0 开始的。

function reConstructBinaryTree(pre, vin)
{
    // write code here
    if (pre.length === 0 || vin.length === 0) return null;
    let root = new TreeNode(pre[0]);
    let root_index = vin.indexOf(pre[0]);   
    root.left = reConstructBinaryTree(pre.slice(1, root_index + 1), vin.slice(0, root_index));
    root.right = reConstructBinaryTree(pre.slice(root_index + 1), vin.slice(root_index + 1));
    return root;
}

三、NC15 求二叉树的层序遍历

给定的二叉树是{3,9,20,#,#,15,7},
[
[3],
[9,20],
[15,7]
]

function levelOrder( root ) {
    // write code here
    if(root==null){return [];}
    let result=[];
    let queue=[root];
    while(queue.length){
        let temp=[];
        let qlen=queue.length;
        for(let i=0;i<qlen;i++){
            let first=queue.shift();
            temp.push(first.val);
            if(first.left!=null){queue.push(first.left);}
            if(first.right!=null){queue.push(first.right);}
        }
        result.push(temp);
    }
    return result;
}
module.exports = {
    levelOrder : levelOrder
};

1、push()是用来在数组末端添加项,并且返回添加后数组的长度;
2、pop()在数组末端移除项,返回移除的数组元素;
3、unshift()在数组前端添加项,并且返回添加后数组的长度;
4、shift()在数组的第一个项(前端)移除,返回移除的数组元素。

四、NC93 设计LRU缓存结构

myMap.entries()
entries()方法返回一个新的包含 [key, value]的 Iterator对象,返回的迭代器的迭代顺序与 Map对象的插入顺序相同。

var myMap = new Map();
myMap.set('0', 'foo');
myMap.set(1, 'bar');
myMap.set({}, 'baz');

var mapIter = myMap.entries();

console.log(mapIter.next().value); // ["0", "foo"]
console.log(mapIter.next().value); // [1, "bar"]
console.log(mapIter.next().value); // [Object, "baz"]

var map=new Map();
值类型就是存储在栈上,引用类型是存储在堆上,但是有个很特殊的情况是,引用类型的名字,是存储在栈上,然后这个名字指向了堆上的一个地址,从而可以直接使用变量名,调用堆上的数据
值类型:

let a = 1;
let b = a;
a = 2;
console.log("a的值是:" + a);
console.log("b的值是:" + b);

在这里插入图片描述
在这里插入图片描述
那么引用类型呢

let a = [1, 2];
let b = a;
a[0] = 0;
console.log("a的值是:" + a);
console.log("b的值是:" + b);

在这里插入图片描述

在这里插入图片描述
正如上面所说exports = module.exports,也就是说他们指向了堆空间的同一个东西,如果对exports进行赋值,那么exports的指向就不一样了,在另外的文件里面就无法再找到通过exports这个变量传递的东西,而module.exports是在执行模块代码中就将module传入到了函数中,所以即使module.exports的值改变也能够在其他文件中进行调用。

//test.js
exports.add = 100;
module.exports = 1;
//test1.js文件
let test = require("./test");
let p = test.add;
let b = test;
console.log("p的值是:" + p);
console.log("b的值是:" + b);
/*
输出结果是:
p的值是:undefined
b的值是:1
*/

可以看出,改变了module.exports的指向后,http://exports.xxx的值在其他文件中也无法调用。

本题解答:

function LRU( operators ,  k ) {
    var map = new Map();
    var temp;
    var result = [];
    for(let i = 0; i < operators.length; i++){
        if(operators[i][0] === 1){
         // map中已经存在该key,说明其对应value需要更新         
            if(map.has(operators[i][1])){
                map.delete(operators[i][1]);
            }else{ //map已满,需要找到最久未访问的删除后,再添加新键值对
                if(map.size==k){
                    const iterator = map.entries();
                    map.delete(iterator.next().value[0]);
                }
            }
            map.set(operators[i][1], operators[i][2]);
        }else{
            if(map.has(operators[i][1])){
                //如果map中有需要查询的key,先保存其值再删除然后添加,可保证这次访问后该键值对为最新插入,不会在删除时误删
                temp = map.get(operators[i][1]);
                map.delete(operators[i][1]);
                map.set(operators[i][1], temp)
                result.push(temp);
            }else{
                result.push(-1);
            }          
        }
    }
    return result;
}
module.exports = {
    LRU : LRU
};

五、NC100 把字符串转化为整数(atoi)

要求:
1.去掉无用的前导空格
2.第一个非空字符为+或者-号时,作为该整数的正负号,如果没有符号,默认为正数
3.判断整数的有效部分:
3.1 确定符号位之后,与之后面尽可能多的连续数字组合起来成为有效整数数字,如果没有有效的整数部分,那么直接返回0
3.2 将字符串前面的整数部分取出,后面可能会存在存在多余的字符(字母,符号,空格等),这些字符可以被忽略,它们对于函数不应该造成影响
3.3 整数超过 32 位有符号整数范围 [−231, 231 − 1] ,需要截断这个整数,使其保持在这个范围内。具体来说,小于 −231的整数应该被调整为 −231 ,大于 231 − 1 的整数应该被调整为 231 − 1
4.去掉无用的后导空格
示例:(对应3.1)
在这里插入图片描述
分析:
1、去掉首尾空格
1.1空字符\s 若干* 开头^ :(^\s*)
1.2或者: |
1.3空字符\s 若干* 结尾$ : (\s*$ )
去掉首尾空格:String.Trim = function(){return this.replace(/(^\s*)|(\s*$)/g, “”);}
PS:空字符包括空格、制表符、垂直制表符、换页符、换行符、回车符。

2、正则表达式修饰符:

  • 修饰符 :i、g、m
    i 执行对大小写不敏感的匹配。
    g 执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)。
    m 执行多行匹配。

3、字符串的寻找与匹配
3.1 .test() 方法用于检测一个字符串是否匹配某个模式,有匹配的值返回 true ,否则返回 false
示例:

var str="Hello world!";
var patt=/Hello/g;
var result=patt.test(str);

与这个表示式是等价的:(r.exec(s) != null)
.exec()返回一个数组存放匹配结果,如果未找到匹配返回null
3.2 indexOf()
返回某指定字符串首次出现的位置,若没出现返回-1

var str = "123";
console.log(str.indexOf("3") != -1 );  // true

六、NC28 最小覆盖子串

1、对象的属性和方法统称为对象的成员
对象属性.和[]
1.1点方法后面跟的必须是一个指定的属性名称,而中括号方法里面可以是变量

var haha = "name";
console.log(obj.haha); // undefined
console.log(obj[haha]); // cedric

1.2中括号方法里面的属性名可以是数字,而点方法后面的属性名不可以是数字

2、判断对象是否包含某属性
2.1 in

// 使用格式
// prop in objectName
// prop:一个字符串类型或者 symbol 类型的属性名或者数组索引(非symbol类型将会强制转为字符串)。
// 检查它(或其原型链)是否包含具有指定名称的属性的对象。
var obj = { 
    name : 'fortune',
    sex : 'monster'
}
'name' in obj;          //true
'toString' in obj       //true
'noExist' in obj        //false

2.2 hasOwnProperty()
判断原型链上的属性是false,这就并不会判断非自身的属性了

hasObj.hasOwnProperty('name')           //true
hasObj.hasOwnProperty('toString')       //false

3、遍历对象属性
3.1 for in

for(var key in obj){
  console.log(key);
}

3.2 Object.keys(xx)/Object.values(xx)
输出key的数组或values数组
[“name”, “career”]

3.3 Object.getOwnProperty

七、字符串出现次数的TopK问题

1、JS字典排序
数组.sort(function(a,b){
return a-b
})//return负数则不交换ab次序
2、JS中…的用法,将表达式展开
3、let m=new Map()
m.set(1,“black”)//添加一个新元素到映射

/**
 * return topK string
 * @param strings string字符串一维数组 strings
 * @param k int整型 the k
 * @return string字符串二维数组
 */
function topKstrings( strings ,  k ) {
    // write code here
    let obj={}
    let res=[]
    strings.sort()
   //通过对象计数出现次数(也可以用map)
    for(let i=0;i<strings.length;i++){
        if(obj.hasOwnProperty(strings[i])){
            obj[strings[i]]++;
        }
        else{
            obj[strings[i]]=1
        }
    }
    //字符串和次数存储为二维数组,方便下一步sort
    for(var key in obj){
        let arr2=[]
            arr2.push(key,obj[key])
            res.push(arr2)
    }
    //出现次数相同则字典升序,不同则降序列
    res.sort(function(a,b){
      if(a[1]==b[1]){
        if(a[0]<b[0])return-1
        else return 1
      }
      else{return b[1]-a[1]}
    })
    res.splice(k)
    return res
}
module.exports = {
    topKstrings : topKstrings
};

已积累的路长,当下所在点

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值