指引
前序:最近打算刷一波算法题,奈何坚持不下来,感觉是方法不对;现在重新调整,按照类型来刷,顺便记录一下刷题过程,加油!!!
刷题步骤:
-
2、
一、基本操作
1、str.charAt(i)的意思是第i个字符在字符串str中所占的位置返回值:
String s = 'AAAAA11DSF';
char c = s.charAt(1);
int aa = s.length()
String aa = s.substring(i, i+2)
s.indexOf(AA); 索引开始位置 : 0
List<String> output = new ArrayList<String>();
--------------------------
char[] str1 = s.toCharArray();
char[] str2 = t.toCharArray();
Arrays.sort(str1);
Arrays.sort(str2);
return Arrays.equals(str1, str2);
2、对字符串的使用:
StringBuilder stringBuilder = new StringBuilder() ;
stringBuilder.append(romans[index] + " ");
3、栈-后进先出
Stack<Character> stack = new Stack<Character>();
stack.pop();
stack.push(c);
stack.isEmpty()
peek 不改变栈的值(不删除栈顶的值),
pop 会把栈顶的值删除。
4、deque双端队列
Deque<Character> deque = new LinkedList<>();
deque.addFirst(123);
deque.addLast(234);
deque.removeLast(111);
deque.getLast();
5、queue队列,先进先出
4、hash
HashMap<Character, Character> mappings = new HashMap<Character, Character>();
mappings.put(')', '(');
mappings.containsKey(c)
全是知识点
Map<String, List> ans = new HashMap<String, List>();
for (String s : strs) {
char[] ca = s.toCharArray();
Arrays.sort(ca);
String key = String.valueOf(ca);
if (!ans.containsKey(key)) ans.put(key, new ArrayList());
ans.get(key).add(s);
}
return new ArrayList(ans.values());
5、List
数组转list
List<String> skuIdList = Arrays.asList("".split(","));
排序,无返回值
Arrays.sort("".split(","));
6、HashMap
两个map相等用equals
7、Queue
Queue<String> queue = new LinkedList<String>();
queue.offer("a"); // 添加元素
TreeNode node = q.poll(); //取出元素
8、链表
LinkedList<Integer> list = new LinkedList<>();
list.add(node.val); //按顺序加到后面
list.addFirst(node.val); //加到开始位置,为了倒序
--------------------------------------------------------------------------------
-
String str.length()
-
char[] result = str.toCharArray(); int length = result.length;
-
StringBuffer aaaa = new StringBuffer(); aaaa.toString()
-
Arrays.sort(arr);
int``[] arr
-
int``max = Math.max(max, continuousLength);
二、二分查询
1、什么样的题型需要二分?
- 时间复杂度是logn
- 升序数组
2、模版框架
注意:对于有目标值的题目有target,可以有相等模式即基本方法,其他的需要构造比较函数
最基本的二分查找算法
int binary_search(int[] nums, int target) {
int left = 0, right = nums.length - 1;
while(left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] < target) {
left = mid + 1;
} else if (nums[mid] > target) {
right = mid - 1;
} else if(nums[mid] == target) {
// 直接返回
return mid;
}
}
// 直接返回
return -1;
}
-------------------------------------------------------------
寻找左侧边界的二分查找
int left_bound(int[] nums, int target) {
int left = 0, right = nums.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] < target) {
left = mid + 1;
} else if (nums[mid] > target) {
right = mid - 1;
} else if (nums[mid] == target) {
// 别返回,锁定左侧边界
right = mid - 1;
}
}
// 最后要检查 left 越界的情况
if (left >= nums.length || nums[left] != target) { return -1;
}
return left;
}
---------------------------------------------------------------
寻找右侧边界的二分查找
int right_bound(int[] nums, int target) {
int left = 0, right = nums.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] < target) {
left = mid + 1;
} else if (nums[mid] > target) {
right = mid - 1;
} else if (nums[mid] == target) {
// 别返回,锁定右侧边界
left = mid + 1;
}
}
// 最后要检查 right 越界的情况
if (right < 0 || nums[right] != target) { return -1;
}
return right;
}
三、滑动窗口
1、这个算法技巧的思路,就是维护一个窗口,不断滑动,然后更新答案
2、通用框架
public String minWindow(String s, String t) {
if(t.length() > s.length()){
return "";
}
HashMap<Character,Integer> need = new HashMap<>();
HashMap<Character,Integer> window = new HashMap<>();
for(int i=0;i< t.length();i++){
char ww = t.charAt(i);
need.put(ww,need.getOrDefault(ww,0)+1);
}
int left = 0;int right = 0;int valid = 0;
int start = 0; int len = Integer.MAX_VALUE;
while(right< s.length()){
char aa = s.charAt(right);
right++;
if(need.containsKey(aa)){
window.put(aa,window.getOrDefault(aa,0)+1);
if(need.get(aa).equals(window.get(aa)) ){
valid++;
}
}
while(valid == need.size()){
if(right - left < len){
start = left;
len = right-left;
}
char bb = s.charAt(left);
left++;
if (need.containsKey(bb)){
if (window.get(bb).equals(need.get(bb))) {
valid--;
}
window.put( bb, window.get( bb ) - 1 );
}
}
}
return len == Integer.MAX_VALUE ? "":s.substring( start, start+len );
}
四、双指针
1、两数之和/三数之和/四数之和
模版:
-
1、先数组排序
-
2、如果是:三个数相加,有一层for循环;四数相加,有两层循环
-
3、while判断
Arrays.sort(nums); for (int i = 0; i < nums.length-2; i++) { int left = i+1; int right = nums.length-1; while(m < n){ int sum = nums[i] + nums[left]+ nums[right]; if(sum == 0){ } else if(sum > 0){ } else {} } } /** * 三数之和 */ public List<List<Integer>> threeSum(int[] nums) { List<List<Integer>> result = new ArrayList<>(); if(nums == null || nums.length <3){ return result; } Arrays.sort(nums); int ns = nums.length; for (int i = 0; i < ns-2; i++) { int m = i+1; int n = nums.length-1; if(nums[i]>0){ break; } if(i>0 && nums[i] == nums[i-1]){ continue; } while(m < n){ int sum = nums[i] + nums[m]+ nums[n]; if(sum == 0){ result.add(Arrays.asList(nums[i],nums[m],nums[n])); while(m<n && nums[m]== nums[m+1]){ m++;} while(m<n&& nums[n] == nums[n-1]){ n--;} m++;n--; } else if(sum > 0){ while(m<n&& nums[n] == nums[n-1]){ n--; } n--; } else if(sum < 0){ while(m<n && nums[m]== nums[m+1]){ m++;} m++; } } } return result; } /** * 四数之和 */ public List<List<Integer>> fourSum(int[] nums, int target) { List<List<Integer>> res = new ArrayList<>(); if(nums == null || nums.length <4){ return res; } Arrays.sort(nums); int n = nums.length; for(int i= 0; i< n-3;i++){ if(i>0 && nums[i]==nums[i-1]){ continue; } for(int j = i+1;j< n-2;j++){ if(j>i+1 && nums[j] == nums[j-1]){ continue; } int left = j+1; int right = n-1; while(left < right){ int sum = nums[i]+nums[j]+nums[left]+nums[right]; if(sum == target){ res.add(Arrays.asList(nums[i],nums[j],nums[left],nums[right])); while(left < right && nums[left] == nums[++left]); while(left < right && nums[right] == nums[--right]); }else if(sum > target){ while(left < right && nums[right] == nums[--right]); }else if (sum < target){ while(left < right && nums[left] == nums[++left]); } } } } return res; }
2、双指针--快慢指针
五、二叉树
1、前序遍历
2、从前序和中序遍历序列构造二叉树
3、二叉树的层序遍历(齿形)
4、二叉树的深度
5、平衡树
平衡树是二叉搜索树和堆合并构成的数据结构,它是一 棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。
二叉树的深度
-----------------------------------------------------------------------------------
二、链表
2、neo4j 节点属性在单向链表上
1、链表基础
3、链表是否有环
4、图解链表
三、大顶堆/小顶堆
1、总结篇 :大顶堆和小顶堆 重点总结,包括从2亿数据中找10个最小的数
小顶堆:队列默认自然顺序排列,小顶堆,不必重写compare
PriorityQueue pq = new PriorityQueue<>();
大顶推:
PriorityQueue left = new PriorityQueue<>(Comparator.reverseOrder());
PriorityQueue Bbb = new PriorityQueue<>((x, y) -> (y - x));