算法

排序

冒泡

public static int[] BubbleSort (int[] arr) {
    for (int i = 0; i < arr.length; i++) {            
        for (int j = 0; j < arr.length - i - 1; j++) {
            if (arr[j] > arr[j+1]) {
                int temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
        }
    }
   return arr;
}
复制代码

选择

public static int[] SelectSort (int[] arr) {
    for (int i = 0; i < arr.length-1; i++) {            
        for (int j = i + 1; j < arr.length; j++) {
            int temp = arr[i];
            if (arr[i] > arr[j]) {
                arr[i] = arr[j];
                arr[j] = temp;
            }
        }
    }
    return arr;
}
复制代码

快排

public int[] MySort (int[] arr) {
        quicksort(arr, 0, arr.length - 1);
        return arr;
    }
    
    public void quicksort(int[] list, int left, int right) {
        if (left < right) {
            int pivot = randompivot(list, left, right);
            quicksort(list,left, pivot-1);
            quicksort(list, pivot+1, right);
        }
    }
    
    public int randompivot(int[] list, int left, int right) {
        int first = list[left];
        while (left < right) {
            while (left < right && list[right] >= first) {
                right--;
            }
            swap(list, left, right);
            
            while(left<right && list[left] <= first) {
                left++;
            }
            swap(list, left, right);
        }
        return left;
    }
    public void swap(int[] list, int left, int right) {
        int temp = list[left];
        list[left] = list[right];
        list[right] = temp;
        
    }
复制代码

堆排序

二分查找

复杂度 O(log2n)

    public static int search(int[] nums, int target) {
		if (nums == null || nums.length == 0) return -1;	
		int left = 0;
		int right = nums.length - 1;
		while (left < right) {
			int mid = left + (right - left) / 2;
			if (nums[mid] < target) {
				left = mid + 1;
			} else {
				right = mid;
			}
		}		
		return nums[left] == target ? left : -1;
	}
复制代码

栈与队列

用栈实现队列

public class Solution {
    Stack<Integer> stack1 = new Stack<Integer>();
    Stack<Integer> stack2 = new Stack<Integer>();
    
    public void push(int node) {
        stack1.push(node);
    }
    
    public int pop() {
        if (stack2.isEmpty()) {
        //如果 outstack 是空的,就把instack 全部 push 到 outstack 里
            while (!stack1.isEmpty()) {
                stack2.push(stack1.pop());
            }
        } 
        // 否则直接弹出
        return stack2.pop();
    }
}
复制代码

字符串

最长无重复子串

    public int maxLength(int[] arr) {
        //用链表实现队列,队列是先进先出的
        Queue<Integer> queue = new LinkedList<>();
        int res = 0;
        for (int c : arr) {
            while (queue.contains(c)) {
                //如果有重复的,队头出队
                queue.poll();
            }
            //添加到队尾
            queue.add(c);
            res = Math.max(res, queue.size());
        }
        return res;
    }
复制代码

数组

斐波那契数列

递归

public int Fibonacci(int n) {
        if (n <= 1) return n;
        return Fibonacci(n-1) + Fibonacci(n-2);
}
复制代码

非递归

public int Fibonacci(int n) {
        if (n <= 1) return n;
        int first = 0;
        int second = 1;
        int temp;
        for (int i = 2; i <= n; i++){
            temp = second;
            second = first + second;
            first = temp;
        }
        return second;
    }
复制代码

有序数组合并

public void merge(int A[], int m, int B[], int n) {

    int aPtr = m - 1, bPtr = n - 1;
//  两数组元素从右至左比较,大的去 A 尾部,直至有一方指针到头为止
    for (int ptr = m + n - 1; aPtr >= 0 && bPtr >= 0; ptr--){
        A[ptr] = A[aPtr] > B[bPtr] ? A[aPtr--] : B[bPtr--];
    }
//  A 指针先走完的情况,B 中剩余元素直接copy至 A 对应位置即可;
    while (bPtr >= 0){
        A[bPtr] = B[bPtr--];
    }

}
复制代码

两数之和

public int[] twoSum (int[] numbers, int target) {
    Map<Integer, Integer> map = new HashMap<>();        
        for (int index = 0; index < numbers.length; index++) {
            int cur = numbers[index];
            if (map.containsKey(target-cur)) {
                return new int[]{map.get(target-cur)+1, index+1};
            }
            map.put(cur, index);
        }
    throw new RuntimeException("results not exits");
}
复制代码

移除有序数组中的重复元素

链表

链表翻转

public ListNode ReverseList(ListNode head) {
        ListNode pre = null;
        ListNode cur = head;
        ListNode next = null;
        while (cur != null) {
            next = cur.next;//先找 next 指针
            cur.next = pre;//往前指
            pre = cur;//往后平移
            cur = next;//往后平移
        }
        return pre;
    }
复制代码

判断是否有环

public class Solution {
    public boolean hasCycle(ListNode head) {
        if (head == null) return false;
        ListNode fast = head;
        ListNode slow = head;
        while (fast != null && fast.next !=null) {
            slow = slow.next;
            fast = fast.next.next;
            if (fast == slow) {
                return true;
            }
        }
        return false;
    }
}
复制代码

链表中环的入口节点

链表环.png

  1. 那么我们可以知道fast指针走过a+b+c+b
  2. slow指针走过a+b
  3. 那么 2*(a+b) = a+b+c+b
  4. 所以a = c
  5. 那么此时让 fast 回到起点,slow 依然停在z,两个同时开始走,一次走一步
  6. 那么它们最终会相遇在y点,正是环的起始点
public class Solution {
    public ListNode detectCycle(ListNode head) {
        if (head == null || head.next == null) return null;
        ListNode fast = head;
        ListNode slow = head;
        while (fast != null && fast.next !=null) {
            slow = slow.next;
            fast = fast.next.next;
            if (fast == slow) {
                fast = head;// fast回到起点
                while (fast != slow) {
                    slow = slow.next;
                    fast = fast.next;
                }
                return slow;     
            }
        }
        return null;
    }
}
复制代码

链表中倒数第K个节点

1.先让first指针先走 K 步;
2.再让first和second指针同时走,first指针走到尾,则second相当于走到倒数第k个节点

public ListNode FindKthToTail (ListNode pHead, int k) {
        if (pHead == null) return pHead;
        ListNode first = pHead;        
        while (k-- > 0) {
            if (first == null) return null;
            first = first.next;
        }
        ListNode second = pHead;
        while (first != null) {
            first = first.next;
            second = second.next;
        }
        return second;
    }
复制代码

合并有序链表

递归

public ListNode mergeTwoLists (ListNode l1, ListNode l2) {
        
        if (l1 == null || l2 == null) {
            return l1 == null ? l2 : l1;
        }
        ListNode first = l1.val < l2.val ? l1 : l2;
        first.next = mergeTwoLists(first.next, first == l1 ? l2 : l1);
        return first;
}
复制代码

非递归

public ListNode mergeTwoLists (ListNode l1, ListNode l2) {
        if (l1 == null) return l2;
        if (l2 == null) return l1;
        ListNode dummy = new ListNode(0);
        ListNode cur = dummy;        
        while (l1 != null && l2 != null) {
            if (l1.val > l2.val) {
                cur.next = l2;
                l2 = l2.next;
            } else {
                cur.next = l1;
                l1 = l1.next;
            }
            cur = cur.next;
        }
        cur.next = l1 == null ? l2 : l1;
        return dummy.next;
    }
复制代码

两个链表的第一个公共结点

284295_1587394616610_37C15C411477833D2C2325823D927212.png

1、假设 链表A 长度为 a,链表B长度为 b,
2、A 走完 a 再将指针指向B 和 B走完b 再将指针指向A,那肯定会相遇;
3、即 a+c+b = b+c+a; (公共点后长度为 c)

此题和链表入口环的节点 题目题解一样的思路。
复制代码
public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
 
        if (pHead1 == null || pHead2 == null) return null;
        ListNode p1 = pHead1;
        ListNode p2 = pHead2;
        
        while (p1 != p2) {
            p1 = p1 != null ? p1.next : pHead2;//到头了就指向 B 
            p2 = p2 != null ? p2.next : pHead1;//到头了就指向 A
        }
        return p1;
    }
复制代码

二叉树

判断是否是完全二叉树和BST

二叉树高度

递归

public int maxDepth (TreeNode root) {
        if(root == null) return 0;
        return 1+ Math.max(maxDepth(root.left), maxDepth(root.right));
    }
复制代码

层序遍历??

层序遍历

 public ArrayList<ArrayList<Integer>> levelOrder (TreeNode root) {
        if (root == null) return new ArrayList();
        ArrayList list = new ArrayList();
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty()) {
            int size = queue.size();            
            ArrayList subList = new ArrayList();
            for (int i = 0; i < size;i++) {
                TreeNode node = queue.poll();
                subList.add(node.val);
                if (node.left != null) {
                    queue.offer(node.left);
                }
                if (node.right != null) {
                    queue.offer(node.right);
                }
            }
            list.add(subList);
        }
        return list;
    }
复制代码

之字形层序遍历

public ArrayList<ArrayList<Integer>> zigzagLevelOrder (TreeNode root) {
        if (root == null) return new ArrayList();        
        ArrayList list = new ArrayList();
        Queue<TreeNode> queue = new LinkedList();
        queue.offer(root);
        while (!queue.isEmpty()) {
            ArrayList sublist = new ArrayList();//存储每一层节点
            for (int i = queue.size(); i >0;i--) {
                TreeNode node = queue.poll();//弹出队列中的节点
                if ((list.size()+1) %2 !=0) {//奇数层,尾部插入
                    sublist.add(node.val);
                } else {//偶数层 头插
                    sublist.add(0, node.val);
                }
                if (node.left != null) {
                    queue.offer(node.left);
                }
                if (node.right != null) {
                    queue.offer(node.right);
                }
            }
            list.add(sublist);
        }        
        return list;
    }
复制代码

二叉树翻转

        public TreeNode invertTree(TreeNode node) {
		if (node == null) {
			return null;
		}
		TreeNode temp = node.left;
		node.left = node.right;
		node.right = temp;
		invertTree(node.left);
		invertTree(node.right);
		return node;
	}
复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享