小辣鸡刷LeetCode

小白刷LeetCode


零、JAVA

1.数组

int[] num = new int [2];
int[] num = {1, 2};
# 可变int[][]:
List<int[]> numL = new ArrayList<int[]>();
int[][] numTrue = numL.toArray(new int[numL.size()][]);
# 不可变int[][]int[][] num = new int[2][2];
int[][] num = {{1,2}, {2,3}};

return new int[]{i, j};
return new int[0];
int[] newnum = Arrays.copyOfRange(arr, lid, rid); #[l, r)
System.arraycopy(old, ol, new, nl, len)# 从原数组的第ol个开始,拷贝到新数组的nl个开始,共len个。

# 变长数组
List<Integer> intList = new ArrayList<Integer>();
List<List<Integer>> intList = new ArrayList<List<Integer>>();
List<int[]> intList = new ArrayList<>();
int length = intList.size();
intList.add(val);
intList.remove(idx);
intList.get(idx);
intList.set(idx, val);
  1. string->char[]:char cArr[] = str.toCharArray(); 或 char c = str.charAt(i);
    string->int: Integer.parseInt(str);

    char[]->string:String str = new String(cArr);
    StringBuffer->string: String str = sb.toString();
    list->string: String str = String.join("", list);
    *->string:String str = String.valueOf(t);

    string->string[]:String strArr[]= str.split("\\s+");(多空格)
    string[]->List:List<String> strL= Arrays.asList(strArr);
    List->string[]:string[] strArr=strL.toArray();

  2. char[]排升序:Arrays.sort(cArr);
    string[]排升序:List<String> strL = Arrays.asList(strArr); Collections.sort(strL);
    int[]排升序:Arrays.sort(intArr);
    重写排序,如int[][] intArrs = [[0,1], [-1, 2]]要求以第一位升序排列:

    Arrays.sort(intArrs, new Comparator<int[]>(){
      public int compare(int[] intArr1, int[] intArr2){
      	return intArr1[0] - intArr2[0];
      }
    });
    
  3. List直接可转hash:Set< String> set = new HashSet(list);

2. 字符串

str.length(); 
str.charAt(idx); str[i];
str.substring(lidx, ridx); #[lidx, ridx);
str.substr(lidx, length);
str = str.trim(); # 去掉开头结尾的空格
str1.equals(str2);
return new StringBuilder(str).reverse().toString();# 逆转字符串

# 可变字符串
StringBuffer sb = new StringBuffer();
sb.append(str);
sb.delete(lidx, ridx);
sb.toString();

String s;
s += "haha";

# string[]和collection的关系
List<String> list = Arrays.asList(strArr);
int len = list.size();
list.add(str);
list.remove(idx);
list.get(idx);
Collections.reverse(list);# 翻转字符串数组的顺序
Collections.sort(list); # 升序
String newStr = String.join(" ", list); # 拼接成新字符串

# String->StringBuffer
# String[]->Collection

2.Map

Map<Integer, Integer> hashmap = new HashMap<Integer, Integer>();
if (hashmap.containsKey(k)) {}
for(Map.entry<Integer, Integer> entry : map.entrySet()){int key = entry.getKey(); int value = entry.getValue();}
hashmap.put(k, v);
hashmap.get(k);
hashmap.remove(k);
hashmap.values();
String str = hashmap.getOrDefault(k, "");#只返回不放入
hashmap.computIfAbsent(k, key->10);#不存在会放入表中

Set<Integer> set = new HashSet<Integer> (); # 无重复数
for (int num : nums){set.add(num);}
set.remove(num);
if (set.contains(num)){}

3.栈 队列

# 用列表模拟栈
List<Character> stack = new ArrayList<Character>();
stack.add(c);
stack.remove(idx);
stack.get(idx);
top = stack.size();

# Stack
Stack<String> s = new Stack<String>();
Deque<TreeNode> s = new LinkedList<TreeNode>();
s.push(str);
while(!s.empty()){s.pop();}
s.peek();#取栈顶

# Queue
Queue<TreeNode> q = new LinkedList<TreeNode>();
q.add(n);
TreeNode n = q.remove();
TreeNode n = q.peek();
size = q.size();

3.指针

if(head==null || head.next==null{return head;}
LineNode t = null;# 空指针
while(fast!=null && fast.next!=null){slow=slow.next;fast=fast.next.next;}# 快慢指针,f=s.n

4.for循环

for(int i=0; i<n; i++){}
for(int i : integers){}	// int[] integers = {1, 2, 3}
for(char c : str.toCharArray()){}
for(Object str : list){}	// String[] strArr = {"a", "b"}; List<String> list = Arrays.toList(strArr);

5. 七七八八

10^9long
10^4可用o(n^2)时间复杂度
mid = left + (right-left)/2;(左倾)
Integer.MAX_VALUE
Math.max(a, b)
Math.pow(a, b)# a的b次方
gcd(a, b)# ab的最大公约数
Random random = new Random();
int r = random.nextInt(10);# 0-10随机取
Character.isDigit(c);# 是否数字
Character.isLetter(c);# 是否是字母
Character.isLetterOrDigit(c);
int num = Integer.parseInt(str);# 字符串转数字
str.length(); intArr.length; intList.size();
str.substring(lidx, ridx); #[lidx, ridx)
str.toLowerCase();
list.add(num); list.get(i);
贝祖定理:要满足3x+4y=5,则5能整除34的最大公约数。

分治、动态规划、回溯、贪心一锅炖:https://zhuanlan.zhihu.com/p/148157101

6. ACM输入输出

import java.util.*;
public class Main {
	// 链表结构
	static class LinkNode{
		int val;
		LinkNode next;
		public LinkNode(int val){
			this.val = val;
		}
	}
	// 树结构
	static class TreeNode{
		int val;
		TreeNode left;
		TreeNode right;
		public TreeNode(){}
		public TreeNode(int val){
			this.val = val;
		}
	}
    public static void main(String[] args) {
    	Scanner in = new Scanner(System.in);
    	// 输入: 1 2 3
    	while(in.hasNextInt()){	int a = in.nextInt;}
    	// 输入: a bb c
    	while(in.hasNextLine()){
    		String str = in.nextLine();
    		String[] sArray = str.split(" ");
    	}
    	// 杂七杂八
    	int a = Integer.parseInt(ch);
    	String sNew = String.join(" ", sArray);
    	
    	// 初始化链表
    	for(int i=0; i<len; i++){
    		p.next = new LinkNode(ints[i]);
    		p = p.next;
    	}
    	// 初始化树
    }
}

7. 分治

时间复杂度:
1个事件被分为a个大小为原来1/b的子事件,合并时间为f(n)
若f(n) = O(n^d):
在这里插入图片描述
如:
在这里插入图片描述

规模变1/2
分解为一个问题1+clogn = O(logn)
分解为两个问题n+nlogn = O(nlogn)

空间复杂度:层数(logn,n为数组内的元素个数)*每层用的空间

二、热题100

1.两数之和

哈希表,先存,再查。O(n)

2.异位词分组

每个单词排序,再查看哈希表里有没有一样的,存到表里。

3.最长连续序列

hashset无重复存储,依次找最小底数(无num-1),对最小底数,依次找增加的数(num++),记录最长的连续长度。

移动零(维持顺序,零放后)

一个指针遍历,另一个指针维护非零。

盛最多水的容器

双指针,短边内移,更新最大容量。

三数之和

关键在于跳过重复组合。
先排序,指针1遍历(如果下一个和自己一样,跳过),指针2和3双指针向中间(如果分别和自己一样,分别跳过)。

无重复字符的最长子串

滑动窗口。右指针一直向右遍历,对每个字母判断,若不在哈希表则存位置,若在哈希表则更新左指针位置为最靠前和更新哈希表位置。

找到字符串中所有字母异位词

String排序:
char[] subChars = sub.toCharArray();
Arrays.sort(subChars);
String ssub = new String(subChars);

和为 K 的子数组

①指针1向右遍历,指针2从1的位置开始向右遍历,计算中间的和。
②哈希表存<前缀和,个数>,当前前缀和-(当前前缀和-target)=target满足则为括号内的个数。

最大子数组和

①动态规划。遍历,是否选用=是否加上前面的更好。
②分治。最大的可能在左边、右边、跨过中间,左右边递归,跨中间算。

合并区间

重写排序,写入、判断左边、改右边。## 相交链表
①A哈希存,B找最先相同的。
②双分支指针,循环并交错转移(a+c+b和b+c+a),直到相遇。

反转链表

①前中后指针。
②递归,从后面往前归,每次归的时候要先反连 再断开原来的正连 再指向空。

public ListNode reverseList(ListNode head) {
    if (head == null || head.next == null) {return head;}
    ListNode newHead = reverseList(head.next);
    head.next.next = head;
    head.next = null;
    return newHead;
}

回文链表

①存字符串,字符串两端匹配。
②快慢指针+栈。
③快慢指针+反转后半部分。

环形链表

快慢指针。

环形链表Ⅱ(找环的起始节点)

①哈希表。
②先让快慢指针相遇,再让快指针指到开始,重新与慢指针相遇(s=nb和k=a+nb)。

合并两个有序链表

①双分支指针。
②递归,

两数相加

单数对应相加,记录进位。

删除链表的倒数第 N 个结点

①前后指针,相差N。
②栈,popN个。

两两交换链表中的节点

递归,3个一组,前两个交换。

K 个一组翻转链表

dummy,start,end,next,end是start的后k位。

随机链表的复制

哈希表存同位置的新和旧节点。

有效的括号

左括号=存,否则判断空/右括号。

最小栈

两个栈,另一个存当前最小值。

字符串解码 2[a3[c]]

非]则先取字母再取数字,最后新整合的字母压栈。

每日温度

单调递减(温度)栈存下标,出栈更新ans。

DFS

Deque<TreeNode> stack = new LinkedList<TreeNode>();
while(root!=null || !stack.isEmpty()){
	while(root!=null){
		stack.push(root);
		# print(root)是前序遍历
		root = root.left;
	}
	root = stack.pop();
	# print(root)是中序遍历
	root = root.right;
}

BFS

if(root == null){return null;}
Queue<TreeNode> queue = new Queue<TreeNode>();
queue.add(root);
while(!queue.isEmpty()){
	int size = queue.size();
	while(size > 0){
		TreeNode p = queue.remove();
		if(p.left!=null){queue.add(p.left);}
		if(p.right!=null){queue.add(p.right);}
		size--;
	}
}

二叉树的中序遍历

①inorder(treenode, list),函数inorder直接返回void而非list。
②以root为基础的深搜。while(root!=null || !stack.isEmpty()){while push left; add; right;}

二叉树的最大深度

①递归。
②广搜。每行一清。

翻转二叉树

①左=递归左,右=递归右,左右互换返回根。
②广搜。出队时换其左右。

对称二叉树

①递归(左右)。
②核心思想是左左右右相同(从队列依次提取的两个要一样)。

二叉树的直径

左高+右高,全局ans。

将有序数组转换为二叉搜索树

root为数组中间值,左右子树递归。

验证二叉搜索树

是二叉搜索树 = 中序遍历为递增。

二叉树展开为(只有右孩子的)链表

①root的右子树往左下移,root的左子树往右移,root=root.right。
②右左中。

从前序与中序遍历序列构造二叉树

根据中,分为左右数组,递归。

路径总和 III(父子和为某值的条数)

①外递归:每个节点;内递归:该节点为根时得到的条数。
②前缀和。

二叉树的最近公共祖先

是最近公共祖先 = 传上来的left和right都找到了(非空)。

买卖股票的最佳时机

前i天的最低价格,前i天的最低利润。

跳跃游戏(能否到)

在每个能到达的位置,记录当前位置的最大能力(maxR = maxR || i+len(i))。

跳跃游戏 II(最小跳数)

一开始最远能跳到哪,第二次在该范围内最远能跳到哪。在最远的地方step++,回退范围不用管step。

划分字母区间

start, max(endc, end)。

搜索插入位置(二分)

找第一个大于等于target的位置即可。

搜索二维矩阵

①行遍历,每行二分。
②从左下或右上开始找,BTS。
③矩阵转数组,matrix[pos/row][pos%col]。

在排序数组中查找元素的第一个和最后一个位置

两次二分,第一次找到target后记录first并让right=mid-1,第二次找到target后记录last并让left=mid+1。

搜索旋转排序数组

二分必有一部分有序另一部分无序,判断有序=端点有序,判断target在哪个部分然后将左右指针指过去。

动态规划:

爬楼梯

ans[i]=ans[i-1]+ans[i-2]

杨辉三角

List<List< Integer>>

打家劫舍(隔一个抢)

钱[i] = 抢前i-1个 或 抢前i-2个和当前的。

零钱兑换

i的硬币数c[i] = 1 + min{c[i - j]},如果不能组成则一定是个数大于总金额的值。

完全平方数

动态规划。如零钱兑换。

单词拆分

动态规划。如果中前为正确,且中后存在,则当前正确。

乘积最大子数组

动态规划。因为是乘法,所以仅维护dpmax不够,还要dpmin,三者同求min max。

分割等和子集

动态规划。等价于是否有数加起来为和的一半。
首先排除:奇数个、和为奇数、最大值大于和的一半。
然后背包:new dp[len][sum/2+1]、dp[i][0]=T、dp[i][num[0]]=T、如果当前numi比j大必不取numi,此时dp[i][j]=dp[i-1][j]、如果当前numi比小则取决于dp[i-1][j]和dp[i-1][j-num[i]]。

矩阵置零

用第一行第一列作标记,因为他们会被覆盖,所以先判断他们的。

螺旋矩阵

方向数组。

顺时针旋转图像

原矩阵行->新矩阵列。

搜索二维矩阵 II

z字形往左下判断。

腐烂的橘子

bfs求最短路径。

三、面试经典150

1. 合并两个有序数组

①先合并再Arrays.sort(arr);②从后往前三指针。

2. 移除元素

①两个左指针,一个找需要前移保留的的元素,一个找可以覆盖的移除元素。②两个双向指针,左边的找需要移除的,右边作为候选替代移除元素。

3. 删除有序数组里的重复项Ⅰ

两个左指针

4. 删除有序数组里的重复项Ⅱ

两个左指针,判断[front-2]?=[tail]

5. 多数元素

①哈希表存次数。
②排序后的n/2位置。
③分治:出、分、算。

6. 轮转数组

①newPos = (ind + k) % length。
②翻转3次:总、左、右。

7. 买卖股票的最佳时机Ⅰ

动态规划

8. 买卖股票的最佳时机Ⅱ

收集所有上坡差

9. 跳跃游戏Ⅰ(能否到达)

贪心,维护最大右边界,先判断是否在界内再判断其是否大于总长。

10. 跳跃游戏Ⅱ(几步到达)

贪心,维护右结束,每到达一次右结束,则用最大右边界更新右结束并步数+1。

11. H指数

排序后,被引用指数>=有多少文献。

12. O(1) 时间插入、删除和获取随机元素

可变数组、哈希表。

13. 除自身以外数组的乘积

前缀和,左右乘积列表。

14. 加油站

找到最后一个差为负的位置,若最终能走完全程,则其下一个位置为所求。

15. 分发糖果

从左数,从右数,求最大。

16. 接雨水

①动态规划,从左数,从右数,求差。
②左右指针:左/右指针都有左&右最大,但只有左指针的左最大右指针的右最大是因遍历而确定的,但通过推理可知,左指针的右最大一定比右指针的右最大还大。所以只要左指针列的左最大大于右指针列的右最大,就可以说明右指针列可以积攒雨水。 同样,只要右指针列的右最大大于左指针列的左最大,就可以说明左指针列可以积攒雨水

17. 罗马数字转整数

哈希表存取。从后往前看,若当前值小于后面的值则减去当前值,否则加上当前值。

18. 整数转罗马数字

13种类型,从大到小排,依次遍历,整数减去一个小于该整数的最大类型,StringBuffer存新增罗马。

19. 最后一个单词的长度

①str.split(" ");
②从后往前找单词。

20. 最长公共前缀

①横向遍历,维护一个前缀,每次将字符串和这个前缀对比。
②纵向遍历,依次比较所有单词的同一个位置字符是否相同,不相同或到达某单词末尾则返回前一个位置。
③分治,出、分、算。

21. 反转字符串里的单词

①s.trim(); s.split(“\s+”); Arrays.asList(sArr); Collections.reverse(sList); String.join(" ", sList);。
②从后往前,两个指针,StringBuffer存。

22. N字形变换

List<StringBuffer>,立flag,row += flag。

28. 找出字符串中第一个匹配项的下标

KMP。

判断子序列

匹配成功两指针同时右移,否则只长指针移。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值