Algorithm
Tips for beginner:
#include<iostream>
using namespace std;
int main(){
for(int i = 0; i< 10;i++){
cout << i<<endl; //输出10个数,0-9
}
cout << endl;
for(int i = 0; i <= 10; i++){
cout << i << endl; // 输出11个数,0-10
}
return 0;
}
二分查找(前闭后开)
//注意是排过序的数组
class Solution {
public int search(int[] nums,int target) {
int left = 0, right = nums.length;
while(left < right) {
int mid = left + ((right - left) >> 1);
if(nums[mid] == target) {
return mid;
} else if (nums[mid] < target) {
left = mid + 1;
} else if (nums[mid] > target) {
right = mid;
}
}
return -1;
}
}
Leetcode27 移除元素
//暴力解法C++
class Solution {
public:
int removeElement(vector<int>& nums,int val) {
int size = nums.size();
for(int i = 0; i< size; i++) {
if (nums[i] == val) {
for(int j = i +1 ; j<size; j++) {
nums[j - 1] = nums[j];
}
i --;
size--;
}
}
return size;
}
};
//双指针
class Solution {
public int removeElement(int[] nums,int val) {
int fast = 0;
int slow = 0;
for(slow = 0; fast <nums.length; fast++) {
if (nums[fast] != val) {
nums[slow++] = nums[fast];
}
}
return slow;
}
}
Leetcode209 长度最小的子数组
//暴力解法C++
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int sum = 0;
int n = nums.size();
int result = INT_MAX; //最终的结果
//如果想得到数组中最小值可以min = INT_MAX 想得到最大值可以max = INT_MIN
int subLength = 0;
for(int i = 0; i< n ; i++) {
sum = 0;
for(int j = i; j<n;j++) {
sum += nums[j];
if(sum >= target) {
subLength = j -i +1;
result = result < subLength ? result :subLength;
break;
}
}
}
return result == INT_MAX ? 0 : result; //若result没有被赋值 则返回0
}
};
//滑动窗口法 降n x n -> n
class Solution {
public int minSubArrayLen(int s,int[] nums) {
int sum = 0;
int left = 0; //滑动窗口的初始位置
int result = Integer.MAX_VALUE;
//如果想得到数组中最小值可以min = INT_MAX 想得到最大值可以max = INT_MIN
for (int right = 0; right < nums.length; right++) {
sum += nums[right];
while (sum >= s) {
result = Math.min(result, right - left + 1);
sum -=nums[left++]; //不断变更left(子数组的起始长度)
}
}
return result == Integer.MAX_VALUE ? 0 : result;//若result没有被赋值 则返回0
}
}
Leetcode203 移除链表元素
class Solution {
public ListNode removeElments(ListNode head, int val) {
if (head == null) return head;
ListNode dummy = new ListNode(-1,head);
ListNode pre = dummy;
ListNode cur = head;
while (cur != null) {
if (cur.value = value) {
pre.next = cur.next;
} else {
pre = cur;
}
cur = cur.next;
}
return dummy.next;
}
}
Leetcode206 反转链表
//双指针
class Solution {
public ListNode reverseList(ListNode head) {
ListNode pre = null;
ListNode cur = head;
ListNode temp = null;
while (cur != null) {
temp = cur.next //保存下一个节点
cur.next = pre;
pre = cur; //更新pre和cur指针
cur = temp;
}
return pre;
}
}
//递归法
class Solution {
public ListNode reverseList(ListNode head) {
return reverse(null, head);
}
private ListNode reverse(ListNode pre, ListNode cur) {
if (cur == null) {
return pre;
}
ListNode temp = null;
temp = cur.next;
cur.next = pre;
return reverse(cur,temp);
}
}
Leetcode19 删除链表倒数第N节点
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummy = new ListNode(-1,head);
ListNode slow = dummy;
ListNode fast = dummy;
while (n-- > 0) {
fast = fast.next;
}
fast = fast.next; //fast 多走一步,让slow指向删除节点的上一个节点
while ( fast != null ) {
fast = fast.next;
slow = slow.next;
}
slow.next = slow.next.next;
return dummy.next;
}
}
Leetcode142 环形链表II
public class Solution {
public ListNode detectCycle(ListNode head) {
ListNode slow = head;
ListNode fast = head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
if (fast == slow) { //若两个指针相遇则证明有环
ListNode index1 = fast; //相遇节点
ListNode index2 = head; //头节点
while (index1 != index2) { //相遇节点w
index1 = index1.next;
index2 = index2.next;
}
return index1;
}
}
return null;
}
}
二叉树的定义
public class TreeNode {
int val;
TreeNode left,right;
TreeNode() {}
TreeNode(int val) {this.val = val;}
TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}
二叉树的递归遍历
//Leetcode144 preOrder
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<Integer>();
preorder(root,result);
return result;
}
public void preorder(TreeNode root,List<Integer> result) {
if (root == null) return;
result.add(root.val);
preorder(root.left,result);
preorder(root.right,result);
}
}
//inOrder postOrder 类似-> 更改位置即可
二叉树的迭代遍历
//前序遍历 中-左-右 入栈顺序:中-右-左
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();
if (root == null) return result;
Deque<TreeNode> stack = new LinkedList<TreeNode>;
stack.push(root);
while (!stack.isEmpty()) {
TreeNode node = stack.pop();
result.add(node.val);
if (node.right != null)
stack.push(node.right);
if (node.left != null)
stack.push(node.left);
}
}
}
//中序遍历
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<Integer>();
if (root == null) return result;
Deque<TreeNode> stack = new LinkedList<TreeNode>();
while (root != null || !stack.isEmpty()) {
while (root != null) {
stack.push(root);
root = root.left;
}
root = stack.pop();
result.add(root.val);
root = root.right;
}
return result;
}
}
//后序遍历:左右中 调整前序中左右为中右左(实际入栈为中左右),然后result反转为左右中
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<Integer>();
if (root == null) return result;
Deque<TreeNode> stack = new LinkedList<TreeNode>();
while (!sisEmpty()) {
TreeNode node = stack.pop();
result.add(root.val);
if (node.left != null) {
stack.push(node.left);
}
if (node.right != null) {
stack.push(node.right);
}
}
Collections.reverse(result);
return result;
}
}
二叉树前中后序统一迭代法
//中序:左中右 入栈顺序:右中左
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> result = new LinkedList<>();
Deque<TreeNode> stack = new LinkedList<>();
if (root != null) st.push(root);
while (!= isEmpty()) {
TreeNode node = stack.peek();
if (node != null) {
stack.pop(); //将该节点弹出,避免重复操作,下面再将右中左添加到栈中
if (node.right != null) stack.push(node.right);
stack.push(node); //添加中节点
stack.push(null); //中节点访问过,但是还没有处理,加入空节点作为标记
if (node.left != null) stack.push(node.left);
} else {
stack.pop(); //将空节点弹出
node = stack.peek();
stack.pop();
result.add(node.val);
}
}
return result;
}
}
//后序遍历左右中 入栈顺序:中右左
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> result = new LinkedList<>();
Deque<TreeNode> stack = new LinkedList<>();
if (root != null) st.push(root);
while (!= isEmpty()) {
TreeNode node = stack.peek();
if (node != null) {
stack.pop(); //将该节点弹出,避免重复操作,下面再将右中左添加到栈中
stack.push(node); //添加中节点
stack.push(null); //中节点访问过,但是还没有处理,加入空节点作为标记
if (node.right != null) stack.push(node.right);
if (node.left != null) stack.push(node.left);
} else {
stack.pop(); //将空节点弹出
node = stack.peek();
stack.pop();
result.add(node.val);
}
}
return result;
}
}
//前序:中左右 入栈:右左中
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> result = new LinkedList<>();
Deque<TreeNode> stack = new LinkedList<>();
if (root != null) st.push(root);
while (!= isEmpty()) {
TreeNode node = stack.peek();
if (node != null) {
stack.pop(); //将该节点弹出,避免重复操作,下面再将右中左添加到栈中
if (node.right != null) stack.push(node.right);
if (node.left != null) stack.push(node.left);
stack.push(node); //添加中节点
stack.push(null); //中节点访问过,但是还没有处理,加入空节点作为标记
} else {
stack.pop(); //将空节点弹出
node = stack.peek();
stack.pop();
result.add(node.val);
}
}
return result;
}
}
二叉树的层序遍历
我的方法:队列
Leetcode102
class Solution {
//
public List<List<Integer>> levelOrder(TreeNode root) {
// 外围list 放最后结果
List<List<Integer>> res = new ArrayList<List<Integer>>();
// 队列实现一层一层遍历 先进先出
Queue<TreeNode> que = new LinkedList<>();
if(root != null)
que.offer(root);
while(!que.isEmpty()){
// 当前队列大小
int length = que.size();
// 内层list 放当前层结果
List<Integer> curList = new ArrayList<>();
// 将当前层存入curList中 并将其各自孩子结点拉入队列中
while(length-- > 0){
// 先进先出弹出队头元素
TreeNode curNode = que.poll();
curList.add(curNode.val);
// 非空孩子结点存入队列
if(curNode.left != null)
que.offer(curNode.left);
if(curNode.right != null)
que.offer(curNode.right);
}
// 当前层存入最终结果列表中
res.add(curList);
}
return res;
}
}
//代码随想录
class Solution {
public List<List<Integer>> resList = new ArrayList<List<Integer>>();
public List<List<Integer>> levelOrder(TreeNode root) {
checkFun2(root);
return resList;
}
public void checkFun2(TreeNode node) {
if (node == null) return;
Queue<TreeNode> que = new LinkedList<TreeNode>();
que.offer(node);
while (! que.isEmpty()) {
List<Integer> itemList = new ArrayList<Integer>();
int length = que.size();
while (length > 0) {
TreeNode tmpNode = que.poll();
itemList.add(tmpNode.val);
if (tmpNode.left != null) que.offer(tmpNode.left);
if (tmpNode.right != null) que.offer(tmpNode.right);
length--;
}
resList.add(itemList);
}
}
}
Leetcode199
class Solution {
public List<Integer> rightSideView(TreeNode root) {
List<Integer> res = new ArrayList<Integer>();
if (root == null) return res;
Queue<TreeNode> que = new LinkedList<>();
que.offer(root);
while (! que.isEmpty()) {
int size = que.size();
for (int i = 0; i < size; i++) {
TreeNode node = que.poll();
if (node.left != null) que.offer(node.left);
if (node.right != null) que.offer(node.right);
if (i == size - 1)
res.add(node.val);
}
}
return res;
}
}
Leetcode226 翻转二叉树
//DFS递归 只有中序不可以
class Solution {
public TreeNode invertTree(TreeNode root) {
if (root == null) return null;
invertTree(root.left);
invertTree(root.right);
swapChildren(root);
return root;
}
public void swapChildren(TreeNode root) {
TreeNode tmp = root.left;
root.left = root.right;
root.right = tmp;
}
}
//BFS
class Solution {
public TreeNode invertTree(TreeNode root) {
if (root == null) return null;
ArrayDeque<TreeNode> deque = new ArrayDeque<>();
deque.offer(root);
while (! deque.isEmpty()) {
int size = deque.size();
while (size-- > 0) {
TreeNode node = deque.poll();
swap(node);
if (node.left != null) deque.offer(node.left);
if (node.right != null) deque.offer(node.right);
}
}
return root;
}
public void swap(TreeNode root) {
TreeNode tmp = root.left;
root.left = root.right;
root.right = tmp;
}
}
Leetcode9
class Solution {
public boolean isPalindrome(int x) {
if (x < 0) return false;
StringBuffer sb = new StringBuffer(String.valueOf(x));
StringBuffer reverse = sb.reverse();
if (reverse.toString().equals(String.valueOf(x)))
return true;
return false;
}
}
前缀和
class NumArray{
//前缀和数组
private int[] preSum;
//构造前缀和
public NumArray(int[] nums) {
//preSum[0] = 0,便于计算累加和
preSum = new int[nums.length +1];
//计算nums的累加和
for(int i = 1; i< preSum.length;i++) {
preSum[i] = preSum[i - 1] + nums[i - 1];
}
}
//查询闭区间[left,right]的累加和
public int sumRange(int left,int right){
reurn preSum[right +1] - preSum[left];
}
}
class NumMatrix{
private int[][] preSum;
pubilc NumMatrix(int[][] matrix){
int m = matrix.length, n =matrix[0].length;
if(m ==0 || n ==0) return;
preSum = new int[m+1][n+1];
for(int i =1; i<=m;i++){
preSum[i][j] = preSum[i-1][j]+preSum[i][j-1] +matrix[i-1][j-1] -preSum[i-1][j-1];
}
}
}
public int sumRegion(int x1,int y1,int x2,int y2){
return preSum[x2+1][y2+1] -preSum[x1][y2+1]-preSum[x2+1][y1] +preSum[x1][y1];
}