数组
加一
class Solution {
public int[] plusOne(int[] digits) {
int len = digits.length;
int carry = 1; // 进位1
for (int i=len-1;i>=0;i--){
int digit = digits[i] + carry;
digits[i] = digit % 10;
carry = digit / 10;
}
if(carry == 1){
// [9,9,9]的情况
digits = new int[len+1];
digits[0] = 1;
}
return digits;
}
}
两数相加
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode head=null, tail=null;
int carry = 0;
while(l1!=null || l2!=null){
int sum = carry;
if(l1!=null){
sum += l1.val;
l1 = l1.next;
}
if(l2!=null){
sum += l2.val;
l2 = l2.next;
}
if(head==null){
head = tail = new ListNode(sum%10);
}else{
tail.next = new ListNode(sum%10);
tail = tail.next;
}
carry = sum / 10;
}
if (carry > 0){
tail.next = new ListNode(carry);
}
return head;
}
}
相交链表
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
/**
用双指针pA 、pB循环俩个链表,链表A循环结束就循环链表B,链表A循环结束就循环链表B,
当pA == pB时就是交点,因为两个指针移动的步数一样
*/
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
// 双链表法
if (headA==null || headB==null){
return null;
}
ListNode node1 = headA, node2 = headB;
while(node1 != node2){
node1 = node1 == null ? headB : node1.next;
node2 = node2 == null ? headA : node2.next;
}
return node1;
}
}
环形链表
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public boolean hasCycle(ListNode head) {
// 使用双指针,如果存在环,则快指针一定会追上慢指针
ListNode fast = head;
ListNode slow = head;
while(fast != null && fast.next != null){
fast = fast.next.next;
slow = slow.next;
if(fast == slow) {
return true;
}
}
return false;
}
}
环形链表II
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
// 使用双指针解法
public ListNode detectCycle(ListNode head) {
ListNode fast = head, slow = head;
// 快指针移动两位,慢指针移动一位,相遇说明有环
while(true){
if ( fast==null || fast.next == null){
return null;
}
fast = fast.next.next;
slow = slow.next;
if(fast == slow){
break;
}
}
fast = head;
while(fast != slow){
fast = fast.next;
slow = slow.next;
}
return fast;
}
}
链表中倒数第k个节点
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode getKthFromEnd(ListNode head, int k) {
ListNode fast = head, slow = head;
for(int i=0;i<k;i++){
fast = fast.next;
}
while(fast != null){
fast = fast.next;
slow = slow.next;
}
return slow;
}
}
对链表进行插入排序
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode insertionSortList(ListNode head) {
if(head==null && head.next == null){
return null;
}
ListNode dummyHead = new ListNode(-1);
dummyHead.next = head;
ListNode lastSorted = head; // 记录最后一个排好序的节点位置
ListNode cur = head.next; // 当前要排序的节点
while(cur != null){
if(lastSorted.val <= cur.val){ // 当前元素大于前面已排好序的元素值
lastSorted = lastSorted.next;
}else{
ListNode pre = dummyHead;
// 寻找插入节点位置
while(pre.next.val <= cur.val){
pre = pre.next;
}
// 链表节点交换
lastSorted.next = cur.next;
cur.next = pre.next;
pre.next = cur;
}
// 调整位置
cur = lastSorted.next;
}
return dummyHead.next;
}
}
链表排序
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
// 通过快慢指针确定中间值,进行拆分,再用归并
public ListNode sortList(ListNode head) {
if(head == null || head.next == null){
return head;
}
// 快慢指针移动,寻找中间指针
ListNode slow = head, fast = head;
while(fast.next != null && fast.next.next != null){
fast = fast.next.next;
slow = slow.next;
}
// 找到中间节点
ListNode mid = slow.next;
// 切断链表
slow.next = null;
// 排序左子链表
ListNode left = sortList(head);
// 排序右子链表
ListNode right = sortList(mid);
// 合并链表
return merge(left, right);
}
public ListNode merge(ListNode left, ListNode right){
ListNode head = new ListNode(0);
ListNode temp = head;
while(left != null && right != null){
if(left.val <= right.val){
temp.next = left;
left = left.next;
}else{
temp.next = right;
right = right.next;
}
temp = temp.next;
}
if(left != null){
temp.next = left;
}
if(right != null){
temp.next = right;
}
return head.next;
}
}
二叉树
二叉树的前序遍历
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();
dfs(root, list);
return list;
}
public void dfs(TreeNode root, List<Integer> list){
if(root == null){
return;
}
list.add(root.val);
dfs(root.left, list);
dfs(root.right, list);
}
}
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();
if(root==null) return list;
LinkedList<TreeNode> stack = new LinkedList<>();
TreeNode cur = root;
while(!stack.isEmpty() || cur!=null){
while(cur != null){
list.add(cur.val);
stack.push(cur);
cur=cur.left;
}
TreeNode temp = stack.pop();
if(temp.right != null){
cur = temp.right;
}
}
return list;
}
}
中序遍历
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();
if(root == null) return list;
LinkedList<TreeNode> stack = new LinkedList<>();
TreeNode cur = root;
while(!stack.isEmpty() || cur!=null){
while(cur!=null){
stack.push(cur);
cur = cur.left;
}
TreeNode temp = stack.pop();
list.add(temp.val);
if(temp.right!=null){
cur = temp.right;
}
}
return list;
}
}
后序遍历
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
postOrder(root, res);
return res;
}
public void postOrder(TreeNode root, List<Integer> list){
if(root == null){
return;
}
postOrder(root.left, list);
postOrder(root.right, list);
list.add(root.val);
}
}
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
if(root == null) return res;
LinkedList<TreeNode> stack = new LinkedList<>();
TreeNode prev = null;
while(!stack.isEmpty() || root!=null){
while(root != null){
stack.push(root);
root = root.left;
}
root = stack.pop();
if(root.right == null || root.right == prev){
res.add(root.val);
prev = root;
root = null;
}else{
stack.push(root);
root = root.right;
}
}
return res;
}
}
层序遍历
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> res = new ArrayList();
if(root==null) return res;
Queue<TreeNode> queue = new LinkedList();
queue.add(root);
while(!queue.isEmpty()){
int size = queue.size();
List<Integer> list = new ArrayList();
for(int i=0; i<size; i++){
TreeNode node = queue.poll();
list.add(node.val);
if(node.left!=null) queue.add(node.left);
if(node.right!=null) queue.add(node.right);
}
res.add(list);
}
return res;
}
}
对称二叉树
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public boolean isSymmetric(TreeNode root) {
if(root==null || (root.left==null&&root.right==null)) return true;
return cur(root.left, root.right);
}
public boolean cur(TreeNode left, TreeNode right){
if(left==null && right==null) return true;
if(left==null || right==null) return false;
if(left.val!=right.val) return false;
return cur(left.left, right.right)&cur(left.right, right.left);
}
}
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public boolean isSymmetric(TreeNode root) {
if(root==null || (root.left==null && root.right==null)) return true;
LinkedList<TreeNode> stack = new LinkedList();
stack.add(root.left);
stack.add(root.right);
while(stack.size()>0){
TreeNode left = stack.poll();
TreeNode right = stack.poll();
if(left==null && right==null) continue;
if(left==null || right==null) return false;
if(left.val != right.val) return false;
stack.offer(left.left);
stack.offer(right.right);
stack.offer(left.right);
stack.offer(right.left);
}
return true;
}
}
LRU缓存
class LRUCache {
//双向链表+hashmap
int capacity;
int size;
Map<Integer,Node>hashTable;
Node head;
Node tail;
public LRUCache(int capacity) {
this.capacity=capacity;
this.size=0;
hashTable=new HashMap();
head=new Node();
tail=new Node();
head.next=tail;
tail.pre=tail;
}
public int get(int key) {
Node node = hashTable.get(key);
if(node==null)return -1;
//将node移动到头部
moveToHead(node);
return node.value;
}
public void moveToHead(Node node){
//将node从双向链表删除
removeNode(node);
//将node添加到头节点后面
addToHead(node);
}
public Node removeNode(Node node){
Node preNode=node.pre;
Node nextNode=node.next;
preNode.next=nextNode;
nextNode.pre=preNode;
node.next=null;
node.pre=null;
return node;
}
public void addToHead(Node node){
Node nextNode=head.next;
head.next=node;
node.pre=head;
node.next=nextNode;
nextNode.pre=node;
}
public void put(int key, int value) {
Node node= hashTable.get(key);
if(node!=null){
node.value=value;
moveToHead(node);
return;
}
//添加到缓存
node=new Node(key,value);
hashTable.put(key,node);
//新节点添加到头节点
addToHead(node);
//
this.size++;
if(this.size>this.capacity){
Node rnode=removeTail();
hashTable.remove(rnode.key);
this.size--;
}
}
public Node removeTail(){
Node rnode=tail.pre;
return removeNode(rnode);
}
class Node{
int key;
int value;
Node next;
Node pre;
Node(){};
Node(int key,int value){
this.key=key;
this.value=value;
}
}
}
/**
* Your LRUCache object will be instantiated and called as such:
* LRUCache obj = new LRUCache(capacity);
* int param_1 = obj.get(key);
* obj.put(key,value);
*/
双指针
早餐组合
class Solution {
public int breakfastNumber(int[] staple, int[] drinks, int x) {
Arrays.sort(staple);
Arrays.sort(drinks);
int count = 0;
int left = 0;
int right = drinks.length-1;
while(left<staple.length&&right>=0){
int number = staple[left]+drinks[right];
if(number<=x){
count = (count+right+1)%1000000007;
left++;
}else{
right--;
}
}
return count;
}
}
删除有序数组中的重复项
class Solution {
public int removeDuplicates(int[] nums) {
if(nums.length==0)
return 0;
//计数
int counter = 0;
for(int i=0;i<nums.length;i++){
if(nums[i]!=nums[counter]){
counter++;
nums[counter]=nums[i];
}
}
counter+=1;
return counter;
}
}
移除元素
class Solution {
public int removeElement(int[] nums, int val) {
int index = 0;
for(int i=0; i<nums.length; i++){
if(nums[i]!=val){
nums[index] = nums[i];
index+=1;
}
}
return index;
}
}
重排链表
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public void reorderList(ListNode head) {
if(head==null) return;
// 用空间换时间
ArrayList<ListNode> list = new ArrayList();
ListNode cur = head;
while(cur!=null){
list.add(cur);
cur = cur.next;
}
int size = list.size();
int i = 0;
int j = size - 1;
while(i<j){
list.get(i).next = list.get(j);
i++;
list.get(j).next = list.get(i);
j--;
}
// 防止成环
list.get(i).next = null;
}
}
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public void reorderList(ListNode head) {
// 取中间断开,后半段逆序合并
if(head==null) return;
// 找中间节点
ListNode slow=head, fast=head;
while(fast.next!=null&&fast.next.next!=null){
slow = slow.next;
fast = fast.next.next;
}
ListNode mid = slow;
ListNode l1 = head, l2 = mid.next;
mid.next = null; // 防止产生环
l2 = reverse(l2);
merge(l1, l2);
}
public ListNode reverse(ListNode node){
ListNode pre = null;
ListNode cur = node;
while(cur!=null){
ListNode nextNode = cur.next;
cur.next = pre;
pre = cur;
cur = nextNode;
}
return pre;
}
public void merge(ListNode l1, ListNode l2){
while(l1!=null&&l2!=null){
ListNode next1 = l1.next;
ListNode next2 = l2.next;
l1.next = l2;
l1 = next1;
l2.next = l1;
l2 = next2;
}
}
}
合并两个数组
class Solution {
public void merge(int[] nums1, int m, int[] nums2, int n) {
int len1 = m-1;
int len2 = n-1;
int len = m+n-1;
while(len1>=0 && len2>=0){
nums1[len--] = nums1[len1] > nums2[len2]?nums1[len1--]:nums2[len2--];
}
System.arraycopy(nums2,0,nums1,0,len2+1);
}
}
逆向双指针:
class Solution {
public void merge(int[] nums1, int m, int[] nums2, int n) {
int p1=m-1,p2=n-1;
int tail = m+n-1;
int cur;
while(p1>=0 || p2>=0){
if(p1==-1){
cur = nums2[p2--];
}else if(p2==-1){
cur = nums1[p1--];
}else if(nums1[p1]>nums2[p2]){
cur = nums1[p1--];
}else{
cur = nums2[p2--];
}
nums1[tail--] = cur;
}
}
}
移动零
class Solution {
public void moveZeroes(int[] nums) {
if(nums.length==1) return;
int cur = 0, index = 0;
while(cur < nums.length){
if(nums[cur]!=0){
swap(nums, cur, index);
index++;
}
cur++;
}
}
public void swap(int[] nums, int x, int y){
int temp = nums[x];
nums[x] = nums[y];
nums[y] = temp;
}
}
滑动窗口
https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/solution/hua-dong-chuang-kou-by-powcai/
无重复字符的最长子串
class Solution {
public int lengthOfLongestSubstring(String s) {
if(s.length() == 0) return 0;
HashMap<Character, Integer> map = new HashMap<Character, Integer>();
int max = 0;
int left = 0;
for(int i=0; i < s.length(); i++){
if(map.containsKey(s.charAt(i))){
left = Math.max(left, map.get(s.charAt(i))+1);
}
map.put(s.charAt(i), i);
max = Math.max(max, i-left+1);
}
return max;
}
}
class Solution {
public int lengthOfLongestSubstring(String s) {
int i=0;
int flag = 0;
int length = 0;
int result = 0;
while(i<s.length()){
int pos = s.indexOf(s.charAt(i),flag);
if(pos<i){
if(length>result){
result = length;
}
if(result>=s.length()-pos-1){
return result;
}
length = i-pos-1;
flag = pos+1;
}
length++;
i++;
}
return length;
}
}
位运算
2的幂
class Solution {
public boolean isPowerOfTwo(int n) {
if(n==0) return false;
while((n&1)==0){
n=n>>1;
}
return n==1;
}