leetcode刷题注意点

452 阅读4分钟

桶排序注意点

分桶的时候,因为正数和负数的关系,分桶的策略要注意220题

对于加减相关的都要考虑是否需要 > 0

int abc = (Math.min(Rheight, Lheight) - height[i]);//小心可能小于0
res += abc > 0 ? abc : 0;

Arrays.Stream

int[] nums = new int[n + 1];
return Arrays.stream(nums).max().getAsInt();//生成流,找到最大值

队列与栈的声明

//栈
Deque<Integer> stack = new ArrayDeque<Integer>();
//ArrayDeque 是 Deque 接口的一种具体实现,是依赖于可变数组来实现的。
//ArrayDeque 没有容量限制,可根据需求自动进行扩容。ArrayDeque 可以作为栈来使用,效率要高于 Stack。
//ArrayDeque 也可以作为队列来使用,效率相较于基于双向链表的 LinkedList 也要更好一些。
//注意,ArrayDeque 不支持为 null 的元素。
//Java 中的 Deuqe,即 “double ended queue” 的缩写,是 Java 中的双端队列集合类型
//注意stack已经不用了,因为它继承自vector,这个vector已经不用了
//相较于addLast()这个offerLast是boolean类型的,会返回插入成功与否

Stack,ArrayDeque,LinkedList的区别

//队列
Queue<String> queue = new LinkedList<String>();
**offer,add 区别:**

一些队列有大小限制,因此如果想在一个满的队列中加入一个新项,多出的项就会被拒绝。

这时新的 offer 方法就可以起作用了。它不是对调用 add() 方法抛出一个 unchecked 异常,而只是得到由 offer() 返回的 false。

**poll,remove 区别:**

remove() 和 poll() 方法都是从队列中删除第一个元素。remove() 的行为与 Collection 接口的版本相似, 但是新的 poll() 方法在用空集合调用时不是抛出异常,只是返回 null。因此新的方法更适合容易出现异常条件的情况。

**peek,element区别:**

element() 和 peek() 用于在队列的头部查询元素。与 remove() 方法类似,在队列为空时, element() 抛出一个异常,而 peek() 返回 null。

队列的用法

List的遍历方式

//方法1 集合类的通用遍历方式, 从很早的版本就有, 用迭代器迭代
Iterator it1 = list.iterator(); 
while(it1.hasNext()){
     System.out.println(it1.next()); 
}

//方法2 增强型for循环遍历
for(String value:list){
    System.out.println(value);
}


//方法3 一般型for循环遍历
for(int i = 0;i < list.size(); i ++){
    System.out.println(list.get(i));
}

排序方法

对集合 Collections.sort();
对数组 Arrays.sort();

两个超限名词

TLE:Time Limit Exceeded 时间超限
MLE:Memory Limit Exceeded 内存超限

TLE:Time Limit Exceeded MLE:Memory Limit Exceeded

leetcode提交注意

千万不要带上static,要不容易出错

list的构造函数

image.png

 HashSet<String> ans = new HashSet<>();
 return new ArrayList<>(ans);
 
 Deque<Integer> stack = new ArrayDeque<Integer>();
 ans.add(new ArrayList<Integer>(stack));
 
 List<Integer> cur = new ArrayList<>();
 ans.add(new ArrayList<>(cur));

二叉树排序

先序:中左右
中序:左中右
后序:左右中

集合中键值对集合

   for (Map.Entry<Integer, Integer> entry : cnt.entrySet()) {//cnt是Map集合
                int m = entry.getValue();
                ans += m * (m - 1);
   }

Comparable的比较关系

//下面试利用Collections里的方法,对集合进行排序
Collections.sort(dictionary, (a, b) -> {
  //b在前,倒序; a在前,正序
  if (a.length() != b.length()) return b.length() - a.length();
  //字典序比较
  return a.compareTo(b);
});

2ce58c69532fe5e28d00953733b32df.jpg

移位运算符

移位运算符(>>>),它使用了“零扩展”:无论正负,都在高位插入0>> 表示在高位上随着符号而变

字符串的拼接和StringBuilder快慢的关系

        StringBuilder sb = new StringBuilder();
        while(!queue.isEmpty()){
            Node abc = queue.poll();
            for (int i = 0; i < abc.f; i++){
                sb.append(abc.v);
            }
        }
        return sb.toString();
        16ms
        String res = "";
        while(!queue.isEmpty()){
            Node abc = queue.poll();
            for (int i = 0; i < abc.f; i++){
                res += abc.v;
            }
        }
        return res;
        968ms

求最大公约数

public int gcd(int a, int b) {
    return b != 0 ? gcd(b, a % b) : a;
}

集合的定义

List<Integer> list = new ArrayList<>();

优先级队列

//默认是小根堆
PriorityQueue<Interger> heap = new PriorityQueue<>();

字符串相关

String s = "abc";
//计算字符串的长度
int m = s.length();
//字符串中第几位的值
s.charAt(i);

String转变成int型的
int a = Integer.parseInt(s);
Long b = Long.parseInt(s);
Math.sqrt(a);//开根号

char i = '5';
System.out.println(i == '5');
String abc = "abc";
System.out.println(abc.equals(abc));

String s = "IVIVIV";
将字符串中的IV全部替换成A
s = s.replaceAll("IV", "A");

判断i是不是字母
Character.isLetter(licensePlate.charAt(i))
//将大写字母i转变为小写
Character.toLowerCase(i)

list转化为数组

List<String> list = new ArrayList<>();
//将list转变为数组快捷方法
String[] sids = list.toArray(new String[List.size()]);

取整操作

向上取整用Math.ceil(double a)  
向下取整用Math.floor(double a)
应用:小心1.0,(int)这些
(int)Math.ceil(map.get(i) * 1.0 / (i + 1)) * (i + 1);

字符串和char[]的转换

//char数组转换为String (char array to String)
char[] charArray = {'P','A','N','K','A','J'};
String str = new String(charArray);
//字符串到char数组 (String to char array)
String str = "journaldev.com";
char[] charArr = str.toCharArray();

余数和被除数符号相同

//余数和被除数符号相同
5 % 3 = 1...2
5 / -3 = -1....2

系统最大和最小

//系统最大和最小
System.out.println(Integer.MIN_VALUE);
System.out.println(Integer.MAX_VALUE);
//Integer.MAX_VALUE是2147483647
//Integer.MIN_VALUE是-2147483648

指数和对数

//求对数
//用到了换底公式,直接使用Math.log()这个是以e为底的
double cc=Math.log(x)/Math.log(y);//会失真,因为底层是用double
//求指数
Math.pow(a,b)
//这个直接就是自然对数的底数
System.out.println(E);

基本数组转化为对象数组和List

int[] a={1,3,4};
/**下面是将基本数组转化为对象数组*/
Integer[] ib= IntStream.of(a).boxed().collect(Collectors.toList()).toArray(new Integer[0]); 
System.out.println(Arrays.toString(ib));  // [1, 3, 4] 
//注:强转不可以用(Integer[]) 

/**基本数组转为List就更简单了,去掉toArray即可*/
List<Integer> ls=IntStream.of(a).boxed().collect(Collectors.toList())
System.out.println(ls);   //[1, 3, 4]

Character.isLetterOrDigit()是否为字母或者数字以及逆序方法

给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。
class Solution {
    public boolean isPalindrome(String s) {
        //只考虑数字字符和字母,并且忽略大小写,其他的不考虑,因此最好把其他的剔除掉
        StringBuffer sgood = new StringBuffer();
        int length = s.length();
        for (int i = 0; i < length; i++) {
            char ch = s.charAt(i);
            //判断是否为字母或者数字,Character包装类的静态方法
            if (Character.isLetterOrDigit(ch)) {
                //全变小写
                sgood.append(Character.toLowerCase(ch));
            }
        }
        //逆序
        StringBuffer sgood_rev = new StringBuffer(sgood).reverse();
        return sgood.toString().equals(sgood_rev.toString());
    }
}

注意:java中不能这样用
String abc = "abcde";
for (char i : abc){//不支持
     System.out.println(i);
}

分割字符

分割字符
在java.lang包中有String.split()方法,返回是一个数组。
  1、“.”和“|”都是转义字符,必须得加"\\";
    如果用“.”作为分隔的话,必须是如下写法:
      String.split("\\."),这样才能正确的分隔开,不能用String.split(".");
      如果用“|”作为分隔的话,必须是如下写法:
      String.split("\\|"),这样才能正确的分隔开,不能用String.split("|");
 
 2、如果在一个字符串中有多个分隔符,可以用“|”作为连字符,比如:“acount=? and uu =? or n=?”,把三个都分隔出来,可以用
   String.split("and|or");

<< 和 <<<

<<表示左移,不分正负数,低位补0;
>>表示右移,如果该数为正,则高位补0,若为负数,则高位补1;
>>>表示无符号右移,也叫逻辑右移,即若该数为正,则高位补0,而若该数为负数,则右移后高位同样补0;
详细链接:https://www.cnblogs.com/chuijingjing/p/9405598.html

位运算注意点

位运算一定要加上括号
B = (A & B) << 1;
1<<1是10两位

求一个数的最大公约数

//求一个数的最大公约数
public static long gcd(long m, long n){
        return n == 0 ? m : gcd(n, m % n);
}

遍历Map集合中键值对集合

for (Map.Entry entry : hashMap.entrySet()){
     System.out.println(entry.getKey() + " " + entry.getValue());
}

取出二进制表示中最低位 1

x二进制表示中最低位 1 表示的值
int lowbit(int x) {
        return x & -x;
}
eg: System.out.println(6 & -6);//2

子串、子数组、子序列

子串、子数组是连续的,子序列是不连续的

拷贝数组

拷贝数组
int n = nums1.length;
int[] rec = new int[n];
//复制原数组在前,被赋予值的数组在后面
System.arraycopy(nums1, 0 , rec, 0, n);
////////
int[] ans = nums.clone();

取模的注意事项

//sum每一步都取模后,可能会出现 sum 比 maxn 小的情况,需要把结果规范化到正数的范围内。
//比如 sum = 1e9 + 10, maxn = 10,此时 sum 取过模就是 3,3 - 10 = -7,需要让 -7 再加上个 MOD 从而变成正数
return (sum  - maxn + MOD) % MOD;

对list排序

List<Integer> list = new ArrayList<>();
Collections.sort(res);

s.spilt(" ");//按照空格分隔,中间是两个空字符

image.png

回溯细节:回溯加入add

List<List<Integre>> res = new ArrayList<>();
LinkedList<Integer> path= new LinkedList<>();
res.add(new ArrayList<>(path));

回溯细节:StringBuilder去除最后

StringBuilder temp = new Stringbuilder();//注意这个不加上<>
temp.deleteCharAt(temp.length() - 1);//这个长度算的是temp的长度

回溯细节:必须用LinkedList前面

LinkedList<Integer> path = new LinkedList<>(); //LinkedList<Integer> path注意
path.removeLast();
//才会有这个方法

回溯细节:LinkedList和ArrayList

LinkedList<Integer> list = new LinkedList<>();
ArrayList<Integer> arrayL = new ArrayList<>();
list.removeLast();//也可以针对最后一个去掉
list.remove(int index);//可以传index
list.get(int index);//慢
////////////////////////////
arrayL.remove(int index);//只能传进去index
arrayL.get(int index);//

Arrays的一些用法

int[] dp = new int[bagWeight + 1];
Arrays.toString(dp)

Arrays.asList(1, 3, 4)

int[] result = new int[size];//存放结果
Arrays.fill(result,-1);//默认全部初始化为-1

StringBuilder的一些操作

sb.setCharAt(start, sb.charAt(end));
sb.setCharAt(end, temp);