├── Fizz Buzz ├── JSoffer ├── 二叉树的镜像.md ├── 二维数组中的查找.md ├── 二进制中1的个数.md ├── 从尾到头打印链表.md ├── 包含min函数的栈.md ├── 反转链表.md ├── 变态跳台阶.md ├── 合并两个排序的链表.md ├── 数值的整数次方.md ├── 斐波那契数列.md ├── 旋转数组的最小数字.md ├── 替换空格.md ├── 树的子结构.md ├── 用两个栈实现队列.md ├── 矩形覆盖.md ├── 调整数组顺序使奇数位于偶数前面.md ├── 跳台阶.md ├── 重建二叉树.md ├── 链表中倒数第k个结点.md └── 顺时针打印矩阵.md ├── LeetCode ├── 001.md ├── 1. Two Sum.md ├── 13. Roman to Integer.md ├── 14. Longest Common Prefix.md ├── 2. Add Two Numbers.md ├── 20. Valid Parentheses.md ├── 21. Merge Two Sorted Lists.md ├── 26. Remove Duplicates from Sorted Array.md ├── 27. Remove Element.md ├── 28. Implement strStr().md ├── 3. Longest Substring Without Repeating Characters.md ├── 35. Search Insert Position.md ├── 38. Count and Say.md ├── 7. Reverse Integer.md └── 9. Palindrome Number.md ├── README.md ├── Remove Linked List Elements ├── 不同的路径 II--unique-paths-ii ├── 主元素--majority-number ├── 二分查找--binary-search ├── 二叉树的中序遍历--binary-tree-inorder-traversal ├── 二叉树的前序遍历--binary-tree-preorder-traversal ├── 二叉树的后序遍历--binary-tree-postorder-traversal ├── 二叉树的最大深度--maximum-depth-of-binary-tree ├── 二进制中有多少个1--count-1-in-binary ├── 合并排序数组 II--merge-sorted-array ├── 合并排序数组--merge-sorted-array-ii ├── 在二叉查找树中插入节点--insert-node-in-a-binary-search-tree ├── 字符串查找--strstr ├── 尾部的零--trailing-zeros ├── 恢复旋转排序数组--recover-rotated-sorted-array ├── 插入区间--insert-interval ├── 搜索二维矩阵--search-a-2d-matrix ├── 搜索插入位置--search-insert-position ├── 数组剔除元素后的乘积--product-of-array-exclude-itself ├── 斐波纳契数列--fibonacci ├── 旋转字符串--rotate-string ├── 最大子数组--maximum-subarray ├── 最小子数组--minimum-subarray ├── 比较字符串--compare-strings ├── 矩阵的之字型遍历--matrix-zigzag-traversal ├── 翻转字符串--reverse-words-in-a-string ├── 翻转链表--reverse-linked-list └── 落单的数--single-number /Fizz Buzz: -------------------------------------------------------------------------------- 1 | 给你一个整数n. 从 1 到 n 按照下面的规则打印每个数: 2 | 3 | 如果这个数被3整除,打印fizz. 4 | 如果这个数被5整除,打印buzz. 5 | 如果这个数能同时被3和5整除,打印fizz buzz. 6 | 7 | 样例 8 | 比如 n = 15, 返回一个字符串数组: 9 | 10 | ["1", "2", "fizz", "4", "buzz", "fizz", "7", "8", "fizz", "buzz", "11", "fizz", "13", "14", "fizz buzz"] 11 | 12 | class Solution { 13 | /** 14 | * param n: As description. 15 | * return: A list of strings. 16 | */ 17 | public ArrayList fizzBuzz(int n) { 18 | ArrayList A = new ArrayList(); 19 | for(int i = 1;i <= n;i++){ 20 | if(i%3 == 0&&i%5 == 0){ 21 | A.add("fizz buzz"); 22 | }else if(i%3 == 0&&i%5 != 0){ 23 | A.add("fizz"); 24 | }else if(i%3 != 0&&i%5 == 0){ 25 | A.add("buzz"); 26 | }else{ 27 | A.add(i+""); 28 | } 29 | } 30 | return A; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /JSoffer/二叉树的镜像.md: -------------------------------------------------------------------------------- 1 | #二叉树的镜像 2 | 3 | ##题目描述 4 | 5 | 操作给定的二叉树,将其变换为源二叉树的镜像。 6 | 输入描述: 7 | 二叉树的镜像定义:源二叉树 8 | ``` 9 | 8 10 | / \ 11 | 6 10 12 | / \ / \ 13 | 5 7 9 11 14 | 镜像二叉树 15 | 8 16 | / \ 17 | 10 6 18 | / \ / \ 19 | 11 9 7 5 20 | 21 | ``` 22 | 23 | ``` 24 | /** 25 | public class TreeNode { 26 | int val = 0; 27 | TreeNode left = null; 28 | TreeNode right = null; 29 | 30 | public TreeNode(int val) { 31 | this.val = val; 32 | 33 | } 34 | 35 | } 36 | */ 37 | import java.util.Stack; 38 | 39 | public class Solution { 40 | public void Mirror(TreeNode root) { 41 | if(root == null){ 42 | return; 43 | } 44 | Stack stack = new Stack(); 45 | stack.push(root); 46 | while(!stack.isEmpty()){ 47 | TreeNode node = stack.pop(); 48 | if(node.left != null||node.right != null){ 49 | TreeNode temp = node.left; 50 | node.left = node.right; 51 | node.right = temp; 52 | } 53 | if(node.left!=null){ 54 | stack.push(node.left); 55 | } 56 | if(node.right!=null){ 57 | stack.push(node.right); 58 | } 59 | } 60 | } 61 | } 62 | ``` 63 | -------------------------------------------------------------------------------- /JSoffer/二维数组中的查找.md: -------------------------------------------------------------------------------- 1 | #二维数组中的查找 2 | 3 | ##题目描述 4 | 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。 5 | 请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。 6 | 7 | ###输入描述: 8 | array: 待查找的二维数组 9 | target:查找的数字 10 | 11 | 12 | ###输出描述: 13 | 查找到返回true,查找不到返回false 14 | 15 | ``` 16 | public class Solution { 17 | public boolean Find(int [][] array,int target) { 18 | if(array == null||array.length == 0){ 19 | return false; 20 | } 21 | if(array[0] == null||array[0].length == 0){ 22 | return false; 23 | } 24 | int m = array.length - 1; 25 | int i = 0; 26 | while((m >= 0)&&(i < array[0].length)){ 27 | if(array[m][i] > target){ 28 | m--; 29 | }else if(array[m][i] < target){ 30 | i++; 31 | }else{ 32 | return true; 33 | } 34 | } 35 | return false; 36 | } 37 | } 38 | ``` 39 | -------------------------------------------------------------------------------- /JSoffer/二进制中1的个数.md: -------------------------------------------------------------------------------- 1 | #二进制中1的个数 2 | 3 | ##题目描述 4 | 5 | 输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。 6 | 7 | ``` 8 | public class Solution { 9 | public int NumberOf1(int n) { 10 | int count = 0; 11 | while(n != 0){ 12 | n = n&(n-1); 13 | count++; 14 | } 15 | return count; 16 | } 17 | } 18 | ``` 19 | -------------------------------------------------------------------------------- /JSoffer/从尾到头打印链表.md: -------------------------------------------------------------------------------- 1 | #从尾到头打印链表 2 | 3 | ##题目描述 4 | 输入一个链表,从尾到头打印链表每个节点的值。 5 | 6 | ###输入描述: 7 | 输入为链表的表头 8 | 9 | 10 | ###输出描述: 11 | 输出为需要打印的“新链表”的表头 12 | 13 | ``` 14 | /** 15 | * public class ListNode { 16 | * int val; 17 | * ListNode next = null; 18 | * 19 | * ListNode(int val) { 20 | * this.val = val; 21 | * } 22 | * } 23 | * 24 | */ 25 | ``` 26 | 27 | ``` 28 | import java.util.ArrayList; 29 | public class Solution { 30 | public ArrayList printListFromTailToHead(ListNode listNode) { 31 | ArrayList result = new ArrayList(); 32 | while(listNode != null){ 33 | result.add(0,listNode.val); 34 | listNode = listNode.next; 35 | } 36 | return result; 37 | } 38 | } 39 | ``` 40 | -------------------------------------------------------------------------------- /JSoffer/包含min函数的栈.md: -------------------------------------------------------------------------------- 1 | #包含min函数的栈 2 | 3 | ##题目描述 4 | 5 | 定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数。 6 | 7 | ``` 8 | import java.util.Stack; 9 | public class Solution { 10 | 11 | int min; 12 | Stack stack = new Stack(); 13 | public void push(int x) { 14 | if (stack.isEmpty()){ 15 | stack.push(0); 16 | min = x; 17 | }else{ 18 | stack.push(x - min);//Could be negative if min value needs to change 19 | if (x < min) 20 | min = x; 21 | } 22 | } 23 | public void pop() { 24 | if (stack.isEmpty()) { 25 | return; 26 | } 27 | int pop=stack.pop(); 28 | if (pop < 0) { 29 | min = min - pop;//If negative, increase the min value 30 | } 31 | } 32 | public int top() { 33 | int top = stack.peek(); 34 | if (top > 0){ 35 | return (top + min); 36 | }else{ 37 | return min; 38 | } 39 | } 40 | public int min() { 41 | return min; 42 | } 43 | } 44 | ``` 45 | 46 | ``` 47 | import java.util.Stack; 48 | public class Solution { 49 | int min = Integer.MAX_VALUE;; 50 | Stack stack = new Stack(); 51 | 52 | public void push(int x) { 53 | // only push the old minimum value when the current 54 | // minimum value changes after pushing the new value x 55 | if(x <= min){ 56 | stack.push(min); 57 | min=x; 58 | } 59 | stack.push(x); 60 | } 61 | 62 | public void pop() { 63 | // if pop operation could result in the changing of the current minimum value, 64 | // pop twice and change the current minimum value to the last minimum value. 65 | if(stack.peek() == min) { 66 | stack.pop(); 67 | min = stack.peek(); 68 | stack.pop(); 69 | }else{ 70 | stack.pop(); 71 | } 72 | if(stack.empty()){ 73 | min = Integer.MAX_VALUE; 74 | } 75 | } 76 | 77 | public int top() { 78 | return stack.peek(); 79 | } 80 | 81 | public int min() { 82 | return min; 83 | } 84 | } 85 | ``` 86 | -------------------------------------------------------------------------------- /JSoffer/反转链表.md: -------------------------------------------------------------------------------- 1 | #反转链表 2 | 3 | ##题目描述 4 | 5 | 输入一个链表,反转链表后,输出链表的所有元素。 6 | 7 | ``` 8 | /* 9 | public class ListNode { 10 | int val; 11 | ListNode next = null; 12 | 13 | ListNode(int val) { 14 | this.val = val; 15 | } 16 | }*/ 17 | ``` 18 | 19 | ``` 20 | public class Solution { 21 | public ListNode ReverseList(ListNode head) { 22 | ListNode node = null; 23 | while(head != null){ 24 | ListNode temp = head.next; 25 | head.next = node; 26 | node = head; 27 | head = temp; 28 | } 29 | return node; 30 | } 31 | } 32 | ``` 33 | -------------------------------------------------------------------------------- /JSoffer/变态跳台阶.md: -------------------------------------------------------------------------------- 1 | #变态跳台阶 2 | 3 | ##题目描述 4 | 5 | 一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。 6 | 7 | ``` 8 | public class Solution { 9 | public int JumpFloorII(int target) { 10 | if(target <= 1){ 11 | return target; 12 | } 13 | return 2*JumpFloorII(target-1); 14 | } 15 | } 16 | ``` 17 | 18 | ###分析思路 19 | 关于本题,前提是n个台阶会有一次n阶的跳法。分析如下: 20 | f(1) = 1 21 | f(2) = f(2-1) + f(2-2) //f(2-2) 表示2阶一次跳2阶的次数。 22 | f(3) = f(3-1) + f(3-2) + f(3-3) 23 | ... 24 | f(n) = f(n-1) + f(n-2) + f(n-3) + ... + f(n-(n-1)) + f(n-n) 25 | 26 | 说明: 27 | 1)这里的f(n) 代表的是n个台阶有一次1,2,...n阶的 跳法数。 28 | 2)n = 1时,只有1种跳法,f(1) = 1 29 | 3) n = 2时,会有两个跳得方式,一次1阶或者2阶,这回归到了问题(1) ,f(2) = f(2-1) + f(2-2) 30 | 4) n = 3时,会有三种跳得方式,1阶、2阶、3阶, 31 | 那么就是第一次跳出1阶后面剩下:f(3-1);第一次跳出2阶,剩下f(3-2);第一次3阶,那么剩下f(3-3) 32 | 因此结论是f(3) = f(3-1)+f(3-2)+f(3-3) 33 | 5) n = n时,会有n中跳的方式,1阶、2阶...n阶,得出结论: 34 | f(n) = f(n-1)+f(n-2)+...+f(n-(n-1)) + f(n-n) => f(0) + f(1) + f(2) + f(3) + ... + f(n-1) 35 | 36 | 6) 由以上已经是一种结论,但是为了简单,我们可以继续简化: 37 | f(n-1) = f(0) + f(1)+f(2)+f(3) + ... + f((n-1)-1) = f(0) + f(1) + f(2) + f(3) + ... + f(n-2) 38 | f(n) = f(0) + f(1) + f(2) + f(3) + ... + f(n-2) + f(n-1) = f(n-1) + f(n-1) 39 | 可以得出: 40 | f(n) = 2*f(n-1) 41 | 42 | 7) 得出最终结论,在n阶台阶,一次有1、2、...n阶的跳的方式时,总得跳法为: 43 | | 1 , (n=0) 44 | f(n) = | 1 , (n=1) 45 | | 2*f(n-1), (n>=2) 46 | -------------------------------------------------------------------------------- /JSoffer/合并两个排序的链表.md: -------------------------------------------------------------------------------- 1 | #合并两个排序的链表 2 | 3 | ##题目描述 4 | 5 | 输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。 6 | 7 | ``` 8 | public class Solution { 9 | public ListNode Merge(ListNode list1,ListNode list2) { 10 | if (list1 == null || list2 == null) { 11 | return list1 == null ? list2 : list1; 12 | } 13 | ListNode head = null; 14 | if (list1.val < list2.val) { 15 | head = list1; 16 | head.next = Merge(list1.next, list2); 17 | } else { 18 | head = list2; 19 | head.next = Merge(list1, list2.next); 20 | } 21 | return head; 22 | } 23 | } 24 | ``` 25 | -------------------------------------------------------------------------------- /JSoffer/数值的整数次方.md: -------------------------------------------------------------------------------- 1 | #数值的整数次方 2 | 3 | ##题目描述 4 | 5 | 给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。 6 | 7 | 8 | ``` 9 | public class Solution { 10 | public double Power(double base, int exponent) { 11 | 12 | } 13 | } 14 | ``` 15 | -------------------------------------------------------------------------------- /JSoffer/斐波那契数列.md: -------------------------------------------------------------------------------- 1 | #斐波那契数列 2 | 3 | ##题目描述 4 | 5 | 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项。 6 | 7 | ``` 8 | public class Solution { 9 | public int Fibonacci(int n) { 10 | if(n <= 1){ 11 | return n; 12 | } 13 | int f0 = 0; 14 | int f1 = 1; 15 | for(int i = 2;i <= n;i++){ 16 | int t = f1; 17 | f1 = f0 + f1; 18 | f0 = t; 19 | } 20 | return f1; 21 | } 22 | } 23 | ``` 24 | -------------------------------------------------------------------------------- /JSoffer/旋转数组的最小数字.md: -------------------------------------------------------------------------------- 1 | #旋转数组的最小数字 2 | 3 | ##题目描述 4 | 5 | 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 6 | 输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。 7 | 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 8 | NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。 9 | 10 | ``` 11 | import java.util.ArrayList; 12 | public class Solution { 13 | public int minNumberInRotateArray(int [] array) { 14 | if(array == null||array.length == 0){ 15 | return 0; 16 | } 17 | int index = array[0]; 18 | for(int i = 1;i < array.length;i++){ 19 | if(array[i] >= index){ 20 | index = array[i]; 21 | }else{ 22 | return array[i]; 23 | } 24 | } 25 | return array[0];//全部数据旋转,相当于没有旋转,最小数即为第一个数 26 | } 27 | } 28 | ``` 29 | -------------------------------------------------------------------------------- /JSoffer/替换空格.md: -------------------------------------------------------------------------------- 1 | #替换空格 2 | 3 | ##题目描述 4 | 请实现一个函数,将一个字符串中的空格替换成“%20”。 5 | 例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。 6 | 7 | ``` 8 | public class Solution { 9 | public String replaceSpace(StringBuffer str) { 10 | if(str == null||str.length() == 0){ 11 | return ""; 12 | } 13 | StringBuffer sb = new StringBuffer(); 14 | for(int i = 0;i < str.length();i++){ 15 | if(str.charAt(i) == ' '){ 16 | sb.append("%20"); 17 | }else{ 18 | sb.append(str.charAt(i)); 19 | } 20 | } 21 | return sb.toString(); 22 | } 23 | } 24 | ``` 25 | -------------------------------------------------------------------------------- /JSoffer/树的子结构.md: -------------------------------------------------------------------------------- 1 | #树的子结构 2 | 3 | ##题目描述 4 | 5 | 输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构) 6 | 7 | ``` 8 | public class Solution { 9 | public boolean HasSubtree(TreeNode root1,TreeNode root2) { 10 | if(root2 == null){ 11 | return false; 12 | } 13 | if(root1 == null){ 14 | return false; 15 | } 16 | return IsSubtree(root1,root2)||IsSubtree(root1.left,root2)||IsSubtree(root1.right,root2); 17 | 18 | } 19 | public boolean IsSubtree(TreeNode root1,TreeNode root2){ 20 | if(root2 == null){ 21 | return true; 22 | } 23 | if(root1 == null){ 24 | return false; 25 | } 26 | if(root1.val == root2.val){ 27 | return IsSubtree(root1.left,root2.left)&&IsSubtree(root1.right,root2.right); 28 | }else{ 29 | return false; 30 | } 31 | } 32 | } 33 | ``` 34 | -------------------------------------------------------------------------------- /JSoffer/用两个栈实现队列.md: -------------------------------------------------------------------------------- 1 | #用两个栈实现队列 2 | 3 | ##题目描述 4 | 用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。 5 | 6 | ``` 7 | import java.util.Stack; 8 | 9 | public class Solution { 10 | Stack stack1 = new Stack(); 11 | Stack stack2 = new Stack(); 12 | 13 | public void push(int node) { 14 | stack1.push(node); 15 | } 16 | 17 | public int pop() { 18 | while(!stack2.isEmpty()){ 19 | return stack2.pop(); 20 | } 21 | while(!stack1.isEmpty()){ 22 | stack2.push(stack1.pop()); 23 | } 24 | return stack2.pop(); 25 | } 26 | } 27 | ``` 28 | -------------------------------------------------------------------------------- /JSoffer/矩形覆盖.md: -------------------------------------------------------------------------------- 1 | #矩形覆盖 2 | 3 | ##题目描述 4 | 5 |

我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?

6 | 7 | ``` 8 | public class Solution { 9 | public int RectCover(int target) { 10 | if(target <= 2){ 11 | return target; 12 | } 13 | int f0 = 1; 14 | int f1 = 2; 15 | for(int i = 3; i <= target;i++){ 16 | int t = f1; 17 | f1 = f0 + f1; 18 | f0 = t; 19 | } 20 | return f1; 21 | } 22 | } 23 | ``` 24 | -------------------------------------------------------------------------------- /JSoffer/调整数组顺序使奇数位于偶数前面.md: -------------------------------------------------------------------------------- 1 | #调整数组顺序使奇数位于偶数前面 2 | 3 | ##题目描述 4 | 5 | 输入一个整数数组,实现一个函数来调整该数组中数字的顺序, 6 | 使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分, 7 | 并保证奇数和奇数,偶数和偶数之间的相对位置不变。 8 | 9 | ``` 10 | public class Solution { 11 | public void reOrderArray(int [] array) { 12 | if(array == null||array.length==0){ 13 | return; 14 | } 15 | for(int i = 0;i < array.length;i++){ 16 | for(int j = array.length-1;j>i;j--){ 17 | if(array[j]%2==1&&array[j-1]%2==0){ 18 | int t = array[j]; 19 | array[j] = array[j-1]; 20 | array[j-1] = t; 21 | } 22 | } 23 | } 24 | } 25 | } 26 | ``` 27 | -------------------------------------------------------------------------------- /JSoffer/跳台阶.md: -------------------------------------------------------------------------------- 1 | #跳台阶 2 | 3 | ##题目描述 4 | 5 | 一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。 6 | 7 | ``` 8 | public class Solution { 9 | public int JumpFloor(int target) { 10 | if(target <= 2){ 11 | return target; 12 | } 13 | int f0 = 1; 14 | int f1 = 2; 15 | for(int i = 3;i <= target;i++){ 16 | int t = f1; 17 | f1 = f1 + f0; 18 | f0 = t; 19 | } 20 | return f1; 21 | } 22 | } 23 | ``` 24 | F(0) = 0; 25 | F(1) = 1; 26 | F(2) = 2; 27 | F(3) = 3; 28 | F(4) = 5; 29 | ... 类似于斐波那契数列问题 30 | -------------------------------------------------------------------------------- /JSoffer/重建二叉树.md: -------------------------------------------------------------------------------- 1 | #重建二叉树 2 | 3 | ##题目描述 4 | 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。 5 | 例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。 6 | 7 | ``` 8 | /** 9 | * Definition for binary tree 10 | * public class TreeNode { 11 | * int val; 12 | * TreeNode left; 13 | * TreeNode right; 14 | * TreeNode(int x) { val = x; } 15 | * } 16 | */ 17 | ``` 18 | 解法一: 19 | ``` 20 | public class Solution { 21 | public TreeNode reConstructBinaryTree(int [] pre,int [] in) { 22 | if(pre.length == 0||in.length == 0){ 23 | return null; 24 | } 25 | TreeNode node = new TreeNode(pre[0]); 26 | for(int i = 0; i < in.length; i++){ 27 | if(pre[0] == in[i]){ 28 | node.left = reConstructBinaryTree(Arrays.copyOfRange(pre, 1, i+1), Arrays.copyOfRange(in, 0, i)); 29 | node.right = reConstructBinaryTree(Arrays.copyOfRange(pre, i+1, pre.length), Arrays.copyOfRange(in, i+1,in.length)); 30 | } 31 | } 32 | return node; 33 | } 34 | } 35 | ``` 36 | 备注: 37 | Arrays.copyOfRange(int [] a, int start, int end) 拷贝数组可以选定范围,如果超过就用默认值填充。 38 | start(包含) 39 | end(不包含) 40 | 41 | 42 | 解法二: 43 | ``` 44 | public class Solution { 45 | public TreeNode reConstructBinaryTree(int [] pre,int [] in) { 46 | if(pre.length == 0||in.length == 0){ 47 | return null; 48 | } 49 | return constructBinaryTree(pre, in, 0, pre.length-1, 0, in.length-1); 50 | } 51 | private TreeNode constructBinaryTree(int [] pre, int [] in, int startPre, int endPre, int startIn, int endIn){ 52 | if(startPre > endPre||startIn > endIn){ 53 | return null; 54 | } 55 | TreeNode node = new TreeNode(pre[startPre]); 56 | for(int i = startIn;i <= endIn; i++){ 57 | if(pre[startPre] == in[i]){ 58 | node.left = constructBinaryTree(pre, in, startPre+1, i+startPre-startIn, startIn, i-1); 59 | node.right = constructBinaryTree(pre, in, i-startIn+startPre+1, endPre ,i+1, endIn); 60 | } 61 | } 62 | return node; 63 | } 64 | } 65 | ``` 66 | -------------------------------------------------------------------------------- /JSoffer/链表中倒数第k个结点.md: -------------------------------------------------------------------------------- 1 | #链表中倒数第k个结点 2 | 3 | ##题目描述 4 | 5 | 输入一个链表,输出该链表中倒数第k个结点。 6 | 7 | 8 | ``` 9 | /* 10 | public class ListNode { 11 | int val; 12 | ListNode next = null; 13 | 14 | ListNode(int val) { 15 | this.val = val; 16 | } 17 | }*/ 18 | 19 | public class Solution { 20 | public ListNode FindKthToTail(ListNode head, int k) { 21 | if(head == null || k<=0){ 22 | return null; 23 | } 24 | ListNode pre = head; 25 | ListNode last = head; 26 | for(int i = 1; i < k;i++){ 27 | if(last.next != null){ 28 | last = last.next; 29 | }else{ 30 | return null; 31 | } 32 | } 33 | while(last.next != null){ 34 | last = last.next; 35 | pre = pre.next; 36 | } 37 | return pre; 38 | } 39 | } 40 | ``` 41 | -------------------------------------------------------------------------------- /JSoffer/顺时针打印矩阵.md: -------------------------------------------------------------------------------- 1 | #顺时针打印矩阵 2 | 3 | ##题目描述 4 | 5 | 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字, 6 | 例如,如果输入如下矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 7 | 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10. 8 | 9 | ``` 10 | import java.util.ArrayList; 11 | public class Solution { 12 | public ArrayList printMatrix(int [][] matrix) { 13 | ArrayList array = new ArrayList(); 14 | if(matrix == null||matrix.length == 0){ 15 | return array; 16 | } 17 | if(matrix[0] == null||matrix[0].length == 0){ 18 | return array; 19 | } 20 | int m =matrix.length ,n = matrix[0].length; 21 | int l = (Math.min(m,n) - 1)/2 +1; 22 | for(int i = 0;i< l;i++){ 23 | for(int j=i;j=i)&&(m-i-1!=i);j--) 28 | array.add(matrix[m-i-1][j]); 29 | for(int j=m-i-2;(j>i)&&(n-i-1!=i);j--) 30 | array.add(matrix[j][i]); 31 | } 32 | return array; 33 | } 34 | } 35 | ``` 36 | -------------------------------------------------------------------------------- /LeetCode/001.md: -------------------------------------------------------------------------------- 1 | ###1. Two Sum 2 | 3 | Given an array of integers, return indices of the two numbers such that they add up to a specific target. 4 | 5 | You may assume that each input would have exactly one solution. 6 | 7 | Example: 8 | Given nums = [2, 7, 11, 15], target = 9, 9 | 10 | Because nums[0] + nums[1] = 2 + 7 = 9, 11 | return [0, 1]. 12 | -------------------------------------------------------------------------------- /LeetCode/1. Two Sum.md: -------------------------------------------------------------------------------- 1 | # 1. Two Sum 2 | 3 | ### Given an array of integers, return indices of the two numbers such that they add up to a specific target. 4 | 5 | ### You may assume that each input would have exactly one solution, and you may not use the same element twice. 6 | 7 | 8 | ### Example: 9 | ```java 10 | Given nums = [2, 7, 11, 15], target = 9, 11 | 12 | Because nums[0] + nums[1] = 2 + 7 = 9, 13 | return [0, 1]. 14 | ``` 15 | ### My Solution 16 | 17 | ```java 18 | class Solution { 19 | public int[] twoSum(int[] nums, int target) { 20 | int[] reslut = new int[2]; 21 | Map map = new HashMap(); 22 | int len = nums.length; 23 | for(int i = 0;i < len; i++){ 24 | if(map.containsKey(target - nums[i])){ 25 | reslut[1] = i; 26 | reslut[0] = map.get(target - nums[i]);; 27 | return reslut; 28 | } 29 | map.put(nums[i], i); 30 | } 31 | return reslut; 32 | } 33 | } 34 | ``` 35 | -------------------------------------------------------------------------------- /LeetCode/13. Roman to Integer.md: -------------------------------------------------------------------------------- 1 | # 13. Roman to Integer 2 | 3 | ### Given a roman numeral, convert it to an integer. Input is guaranteed to be within the range from 1 to 3999. 4 | 5 | ### My Solution 6 | 7 | ``` 8 | 思路: 9 | 10 | 首先要清楚罗马数字的组成规则。它本质上是由有限的单个字符组成。针对不同的位以及重复次数限制来组成别的数字。它们基本的字符就是如下几个: 11 | I: 1 V: 5 X: 10 L: 50 12 | C: 100 D: 500 M: 1000 13 | 14 | 所以给定一个罗马数字,无非就是要将一串罗马数字给解析成对应的阿拉伯数字并将结果加起来。这里该如何对给定的罗马数字串解析就是问题的核心。 15 | 相同的数字连写,所表示的数等于这些数字相加得到的数,例如:III = 3 16 | 小的数字在大的数字右边,所表示的数等于这些数字相加得到的数,例如:VIII = 8 17 | 小的数字,限于(I、X和C)在大的数字左边,所表示的数等于大数减去小数所得的数,例如:IV = 4 18 | 左减数字必须为一位,比如8写成VIII,而非IIX 19 | 右加数字不可连续超过三位,比如14写成XIV,而非XIIII 20 | 在一个数的上面画横线,表示这个数扩大1000倍(本题只考虑3999以内的数,所以用不到这条规则) 21 | 22 | 23 | 根据上述规律可知,通过对字符串的遍历,对于出现前面一个数字不小于后面的就直接相加,而否则的情况则要减一个对应的值。而为了描述这个计算,我们可以将单个的罗马数字符和对应的阿拉伯数字映射起来。 24 | ``` 25 | 26 | ```java 27 | class Solution { 28 | public int romanToInt(String s) { 29 | int nums[]=new int[s.length()]; 30 | for(int i=0;i= strs[i].length() || j >= strs[i + 1].length() || strs[i].charAt(j) != strs[i + 1].charAt(j)){ 14 | return strs[i].substring(0, j); 15 | } 16 | } 17 | return strs[0]; 18 | } 19 | } 20 | ``` 21 | 22 | 23 | ```java 24 | class Solution { 25 | public String longestCommonPrefix(String[] strs) { 26 | if(strs == null || strs.length == 0) return ""; 27 | if(strs == null || strs.length == 0) return ""; 28 | for(int i = 0; i < strs.length; i++) 29 | while(strs[i].indexOf(strs[0]) != 0){ 30 | strs[0] = strs[0].substring(0, strs[0].length() - 1); 31 | } 32 | return strs[0]; 33 | } 34 | } 35 | ``` 36 | -------------------------------------------------------------------------------- /LeetCode/2. Add Two Numbers.md: -------------------------------------------------------------------------------- 1 | # 2. Add Two Numbers 2 | 3 | You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list. 4 | 5 | You may assume the two numbers do not contain any leading zero, except the number 0 itself. 6 | 7 | ``` 8 | Example 9 | Input: (2 -> 4 -> 3) + (5 -> 6 -> 4) 10 | Output: 7 -> 0 -> 8 11 | Explanation: 342 + 465 = 807. 12 | ``` 13 | 14 | ### My Solution 15 | ```java 16 | /** 17 | * Definition for singly-linked list. 18 | * public class ListNode { 19 | * int val; 20 | * ListNode next; 21 | * ListNode(int x) { val = x; } 22 | * } 23 | */ 24 | class Solution { 25 | public ListNode addTwoNumbers(ListNode l1, ListNode l2) { 26 | ListNode result = new ListNode(0); 27 | ListNode current = result; 28 | int flag = 0; 29 | while(l1 != null || l2!= null || flag != 0){ 30 | if (l1 != null) { 31 | flag += l1.val; 32 | l1 = l1.next; 33 | } 34 | if (l2 != null) { 35 | flag += l2.val; 36 | l2 = l2.next; 37 | } 38 | current.next = new ListNode(flag % 10); 39 | flag /= 10; 40 | current = current.next; 41 | } 42 | return result.next; 43 | } 44 | } 45 | ``` 46 | -------------------------------------------------------------------------------- /LeetCode/20. Valid Parentheses.md: -------------------------------------------------------------------------------- 1 | # 20. Valid Parentheses 2 | 3 | Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid. 4 | The brackets must close in the correct order, "()" and "()[]{}" are all valid but "(]" and "([)]" are not. 5 | 6 | ### MySolution 7 | ```java 8 | class Solution { 9 | public boolean isValid(String s) { 10 | Stack stack = new Stack(); 11 | for(char c: s.toCharArray()){ 12 | if(c == '('){ 13 | stack.push(')'); 14 | }else if(c == '['){ 15 | stack.push(']'); 16 | }else if(c == '{'){ 17 | stack.push('}'); 18 | }else if(stack.isEmpty() || c != stack.pop()){ 19 | return false; 20 | } 21 | } 22 | return stack.isEmpty(); 23 | } 24 | } 25 | ``` 26 | -------------------------------------------------------------------------------- /LeetCode/21. Merge Two Sorted Lists.md: -------------------------------------------------------------------------------- 1 | # 21. Merge Two Sorted Lists 2 | 3 | ## Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists. 4 | 5 | ### Example: 6 | 7 | Input: 1->2->4, 1->3->4 8 | 9 | Output: 1->1->2->3->4->4 10 | 11 | 12 | ### My Solution 13 | 14 | ```java 15 | /** 16 | * Definition for singly-linked list. 17 | * public class ListNode { 18 | * int val; 19 | * ListNode next; 20 | * ListNode(int x) { val = x; } 21 | * } 22 | */ 23 | class Solution { 24 | public ListNode mergeTwoLists(ListNode l1, ListNode l2) { 25 | if(l1 == null){ 26 | return l2; 27 | } 28 | if(l2 == null){ 29 | return l1; 30 | } 31 | ListNode result; 32 | if(l1.val >= l2.val){ 33 | result = l2; 34 | result.next = mergeTwoLists(l1, l2.next); 35 | }else{ 36 | result = l1; 37 | result.next = mergeTwoLists(l1.next, l2); 38 | } 39 | return result; 40 | } 41 | } 42 | ``` 43 | -------------------------------------------------------------------------------- /LeetCode/26. Remove Duplicates from Sorted Array.md: -------------------------------------------------------------------------------- 1 | # 26. Remove Duplicates from Sorted Array 2 | 3 | ## Given a sorted array, remove the duplicates in-place such that each element appear only once and return the new length. Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory. 4 | 5 | ``` 6 | Example: 7 | 8 | Given nums = [1,1,2], 9 | Your function should return length = 2, with the first two elements of nums being 1 and 2 respectively. 10 | It doesn't matter what you leave beyond the new length. 11 | ``` 12 | 13 | ### My Solution 14 | 15 | ```java 16 | class Solution { 17 | public int removeDuplicates(int[] nums) { 18 | int result = 1; 19 | for(int i = 1;i < nums.length;i++){ 20 | if(nums[i] != nums[i - 1]){ 21 | nums[result++] = nums[i]; 22 | } 23 | } 24 | return result; 25 | } 26 | } 27 | ``` 28 | -------------------------------------------------------------------------------- /LeetCode/27. Remove Element.md: -------------------------------------------------------------------------------- 1 | # 27. Remove Element 2 | 3 | ## Given an array and a value, remove all instances of that value in-place and return the new length. Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory. The order of elements can be changed. It doesn't matter what you leave beyond the new length. 4 | 5 | ### Example: 6 | 7 | ```java 8 | Given nums = [3,2,2,3], val = 3, 9 | Your function should return length = 2, with the first two elements of nums being 2. 10 | ``` 11 | 12 | ### MySolution 13 | 14 | ```java 15 | class Solution { 16 | public int removeElement(int[] nums, int val) { 17 | int result = 0; 18 | for(int i = 0; i < nums.length; i++){ 19 | if(nums[i] != val){ 20 | nums[result] = nums[i]; 21 | result++; 22 | } 23 | } 24 | return result; 25 | } 26 | } 27 | ``` 28 | -------------------------------------------------------------------------------- /LeetCode/28. Implement strStr().md: -------------------------------------------------------------------------------- 1 | # 28. Implement strStr() 2 | 3 | Implement strStr(). Return the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack. 4 | 5 | ```java 6 | Example 1: 7 | Input: haystack = "hello", needle = "ll" 8 | Output: 2 9 | 10 | Example 2: 11 | Input: haystack = "aaaaa", needle = "bba" 12 | Output: -1 13 | ``` 14 | ### My Solution 15 | ```java 16 | class Solution { 17 | public int strStr(String haystack, String needle) { 18 | for (int i = 0; ; i++) { 19 | for (int j = 0; ; j++) { 20 | if (j == needle.length()) return i; 21 | if (i + j == haystack.length()) return -1; 22 | if (needle.charAt(j) != haystack.charAt(i + j)) break; 23 | } 24 | } 25 | } 26 | } 27 | ``` 28 | -------------------------------------------------------------------------------- /LeetCode/3. Longest Substring Without Repeating Characters.md: -------------------------------------------------------------------------------- 1 | # 3. Longest Substring Without Repeating Characters 2 | 3 | Given a string, find the length of the longest substring without repeating characters. 4 | Examples: 5 | Given "abcabcbb", the answer is "abc", which the length is 3. 6 | Given "bbbbb", the answer is "b", with the length of 1. 7 | Given "pwwkew", the answer is "wke", with the length of 3. Note that the answer must be a substring, "pwke" is a subsequence and not a substring. 8 | 9 | 10 | ### My solution 11 | 12 | ```java 13 | class Solution { 14 | public int lengthOfLongestSubstring(String s) { 15 | int result = 0; 16 | int[] cache = new int[128]; 17 | for (int i = 0, j = 0; i < s.length(); i++) { 18 | j = (cache[s.charAt(i)] > 0) ? Math.max(j, cache[s.charAt(i)]) : j; 19 | cache[s.charAt(i)] = i + 1; 20 | result = Math.max(result, i - j + 1); 21 | } 22 | return result; 23 | } 24 | } 25 | ``` 26 | -------------------------------------------------------------------------------- /LeetCode/35. Search Insert Position.md: -------------------------------------------------------------------------------- 1 | # 35. Search Insert Position 2 | 3 | ## Given a sorted array and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order. You may assume no duplicates in the array. 4 | 5 | ```java 6 | Example 1: 7 | Input: [1,3,5,6], 5 8 | Output: 2 9 | 10 | Example 2: 11 | Input: [1,3,5,6], 2 12 | Output: 1 13 | 14 | Example 3: 15 | Input: [1,3,5,6], 7 16 | Output: 4 17 | 18 | Example 1: 19 | Input: [1,3,5,6], 0 20 | Output: 0 21 | ``` 22 | 23 | ### MySolotion 24 | 25 | ```java 26 | class Solution { 27 | public int searchInsert(int[] nums, int target) { 28 | int min = 0; 29 | int max = nums.length - 1; 30 | while(min <= max){ 31 | int mid = (min + max) / 2; 32 | if(target == nums[mid]){ 33 | return mid; 34 | }else if(target < nums[mid]){ 35 | max = mid - 1; 36 | }else{ 37 | min = mid + 1; 38 | } 39 | } 40 | return min; 41 | } 42 | } 43 | ``` 44 | -------------------------------------------------------------------------------- /LeetCode/38. Count and Say.md: -------------------------------------------------------------------------------- 1 | # 38. Count and Say 2 | 3 | ## The count-and-say sequence is the sequence of integers with the first five terms as following: 4 | 5 | ``` 6 | 1. 1 7 | 2. 11 8 | 3. 21 9 | 4. 1211 10 | 5. 111221 11 | 1 is read off as "one 1" or 11. 12 | 11 is read off as "two 1s" or 21. 13 | 21 is read off as "one 2, then one 1" or 1211. 14 | Given an integer n, generate the nth term of the count-and-say sequence. 15 | ``` 16 | Note: Each term of the sequence of integers will be represented as a string. 17 | 18 | ```java 19 | Example 1: 20 | Input: 1 21 | Output: "1" 22 | 23 | Example 2: 24 | Input: 4 25 | Output: "1211" 26 | ``` 27 | 28 | ### MY Solution 29 | ```java 30 | class Solution { 31 | public String countAndSay(int n) { 32 | if(n <= 0) return null; 33 | int i = 1; 34 | String result = "1"; 35 | while(i < n){ 36 | StringBuilder sb = new StringBuilder(); 37 | int count = 1; 38 | for (int j = 1; j < result.length(); j++) { 39 | if (result.charAt(j) == result.charAt(j - 1)) { 40 | count++; 41 | } else { 42 | sb.append(count); 43 | sb.append(result.charAt(j - 1)); 44 | count = 1; 45 | } 46 | } 47 | 48 | sb.append(count); 49 | sb.append(result.charAt(result.length() - 1)); 50 | result = sb.toString(); 51 | i++; 52 | } 53 | return result; 54 | } 55 | } 56 | ``` 57 | -------------------------------------------------------------------------------- /LeetCode/7. Reverse Integer.md: -------------------------------------------------------------------------------- 1 | # 7. Reverse Integer 2 | 3 | ### Given a 32-bit signed integer, reverse digits of an integer. 4 | 5 | ```java 6 | Example 1: 7 | Input: 123 8 | Output: 321 9 | 10 | Example 2: 11 | Input: -123 12 | Output: -321 13 | 14 | Example 3: 15 | Input: 120 16 | Output: 21 17 | ``` 18 | 19 | ```java 20 | Note: 21 | Assume we are dealing with an environment which could only hold integers within the 32-bit signed integer range. 22 | For the purpose of this problem, assume that your function returns 0 when the reversed integer overflows. 23 | ``` 24 | 25 | 26 | ```java 27 | class Solution { 28 | public int reverse(int x) { 29 | int result = 0; 30 | while(x != 0){ 31 | int num = x % 10; 32 | int newResult = result * 10 + num; 33 | /** assume that your function returns 0 when the reversed integer overflows 34 | unsigned int: 4294967295 (2^32-1) 35 | signed int: 2147483647 (2^31-1) **/ 36 | if ((newResult - num) / 10 != result){ 37 | return 0; 38 | } 39 | result = newResult; 40 | x = x /10; 41 | } 42 | return result; 43 | } 44 | } 45 | ``` 46 | -------------------------------------------------------------------------------- /LeetCode/9. Palindrome Number.md: -------------------------------------------------------------------------------- 1 | # 9. Palindrome Number 2 | 3 | ## Determine whether an integer is a palindrome. Do this without extra space. 4 | 5 | ### NOTE :设n是一任意自然数。若将n的各位数字反向排列所得自然数n1与n相等,则称n为一回文数。例如,若n=1234321,则称n为一回文数;但若n=1234567,则n不是回文数。 6 | 7 | ### My Solution 8 | 9 | ```java 10 | class Solution { 11 | public boolean isPalindrome(int x) { 12 | if(x < 0){ 13 | return false; 14 | } 15 | int index = x; 16 | int result = 0; 17 | while(index != 0){ 18 | result = result * 10 + index % 10; 19 | index = index / 10; 20 | } 21 | return x == result; 22 | } 23 | } 24 | ``` 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CodeEveryday 训练算法思维 2 | 3 | LintCode题解(Java版)------剑指offer题解(Java版)------LeetCode题解(Java版) 4 | 5 | ## LintCode题解 6 | 7 | 8 | ## 剑指offer题解 9 | [替换空格](https://github.com/BaymaxTong/LintCode-Java/blob/master/JSoffer/%E6%9B%BF%E6%8D%A2%E7%A9%BA%E6%A0%BC.md) 10 | 11 | [重建二叉树](https://github.com/BaymaxTong/LintCode-Java/blob/master/JSoffer/%E9%87%8D%E5%BB%BA%E4%BA%8C%E5%8F%89%E6%A0%91.md) 12 | 13 | [二维数组中的查找](https://github.com/BaymaxTong/LintCode-Java/blob/master/JSoffer/%E4%BA%8C%E7%BB%B4%E6%95%B0%E7%BB%84%E4%B8%AD%E7%9A%84%E6%9F%A5%E6%89%BE.md) 14 | 15 | [从尾到头打印链表](https://github.com/BaymaxTong/LintCode-Java/blob/master/JSoffer/%E4%BB%8E%E5%B0%BE%E5%88%B0%E5%A4%B4%E6%89%93%E5%8D%B0%E9%93%BE%E8%A1%A8.md) 16 | 17 | [反转链表](https://github.com/BaymaxTong/LintCode-Java/blob/master/JSoffer/%E5%8F%8D%E8%BD%AC%E9%93%BE%E8%A1%A8.md) 18 | 19 | [用两个栈实现队列](https://github.com/BaymaxTong/LintCode-Java/blob/master/JSoffer/%E7%94%A8%E4%B8%A4%E4%B8%AA%E6%A0%88%E5%AE%9E%E7%8E%B0%E9%98%9F%E5%88%97.md ) 20 | 21 | [旋转数组的最小数字](https://github.com/BaymaxTong/LintCode-Java/blob/master/JSoffer/%E6%97%8B%E8%BD%AC%E6%95%B0%E7%BB%84%E7%9A%84%E6%9C%80%E5%B0%8F%E6%95%B0%E5%AD%97.md) 22 | 23 | [斐波那契数列](https://github.com/BaymaxTong/LintCode-Java/blob/master/JSoffer/%E6%96%90%E6%B3%A2%E9%82%A3%E5%A5%91%E6%95%B0%E5%88%97.md ) 24 | 25 | [跳台阶](https://github.com/BaymaxTong/LintCode-Java/blob/master/JSoffer/%E8%B7%B3%E5%8F%B0%E9%98%B6.md) 26 | 27 | [变态跳台阶](https://github.com/BaymaxTong/LintCode-Java/blob/master/JSoffer/%E5%8F%98%E6%80%81%E8%B7%B3%E5%8F%B0%E9%98%B6.md) 28 | 29 | [矩形覆盖](https://github.com/BaymaxTong/LintCode-Java/blob/master/JSoffer/%E7%9F%A9%E5%BD%A2%E8%A6%86%E7%9B%96.md) 30 | 31 | [二进制中1的个数](https://github.com/BaymaxTong/LintCode-Java/blob/master/JSoffer/%E4%BA%8C%E8%BF%9B%E5%88%B6%E4%B8%AD1%E7%9A%84%E4%B8%AA%E6%95%B0.md) 32 | 33 | [数值的整数次方](https://github.com/BaymaxTong/LintCode-Java/blob/master/JSoffer/%E6%95%B0%E5%80%BC%E7%9A%84%E6%95%B4%E6%95%B0%E6%AC%A1%E6%96%B9.md) 34 | 35 | [调整数组顺序使奇数位于偶数前面](https://github.com/BaymaxTong/LintCode-Java/blob/master/JSoffer/%E8%B0%83%E6%95%B4%E6%95%B0%E7%BB%84%E9%A1%BA%E5%BA%8F%E4%BD%BF%E5%A5%87%E6%95%B0%E4%BD%8D%E4%BA%8E%E5%81%B6%E6%95%B0%E5%89%8D%E9%9D%A2.md) 36 | 37 | [链表中倒数第k个结点](https://github.com/BaymaxTong/LintCode-Java/blob/master/JSoffer/%E9%93%BE%E8%A1%A8%E4%B8%AD%E5%80%92%E6%95%B0%E7%AC%ACk%E4%B8%AA%E7%BB%93%E7%82%B9.md) 38 | 39 | [合并两个排序的链表](https://github.com/BaymaxTong/LintCode-Java/blob/master/JSoffer/%E5%90%88%E5%B9%B6%E4%B8%A4%E4%B8%AA%E6%8E%92%E5%BA%8F%E7%9A%84%E9%93%BE%E8%A1%A8.md) 40 | 41 | [树的子结构](https://github.com/BaymaxTong/LintCode-Java/blob/master/JSoffer/%E6%A0%91%E7%9A%84%E5%AD%90%E7%BB%93%E6%9E%84.md) 42 | 43 | [二叉树的镜像](https://github.com/BaymaxTong/LintCode-Java/blob/master/JSoffer/%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E9%95%9C%E5%83%8F.md) 44 | 45 | [顺时针打印矩阵](https://github.com/BaymaxTong/LintCode-Java/blob/master/JSoffer/%E9%A1%BA%E6%97%B6%E9%92%88%E6%89%93%E5%8D%B0%E7%9F%A9%E9%98%B5.md) 46 | 47 | [包含min函数的栈](https://github.com/BaymaxTong/LintCode-Java/blob/master/JSoffer/%E5%8C%85%E5%90%ABmin%E5%87%BD%E6%95%B0%E7%9A%84%E6%A0%88.md) 48 | 49 | [栈的压入、弹出序列] 50 | 51 | [从上往下打印二叉树] 52 | 53 | [二叉搜索树的后序遍历序列] 54 | 55 | [二叉树中和为某一值的路径] 56 | 57 | 58 | 59 | 60 | 61 | ## LeetCode-Java 。题解 62 | 63 | ##每日编程训练练习,及时阻止老年痴呆 64 | 65 | [1. Two Sum](https://github.com/BaymaxTong/LintCode-Java/tree/master/LeetCode/1.%20Two%20Sum.md) 66 | 67 | [2. Add Two Numbers](https://github.com/BaymaxTong/LintCode-Java/tree/master/LeetCode/2.%20Add%20Two%20Numbers.md) 68 | 69 | [3. Longest Substring Without Repeating Characters](https://github.com/BaymaxTong/LintCode-Java/tree/master/LeetCode/3.%20Longest%20Substring%20Without%20Repeating%20Characters.md) 70 | 71 | 72 | 73 | [7. Reverse Integer](https://github.com/BaymaxTong/LintCode-Java/tree/master/LeetCode/7.%20Reverse%20Integer.md) 74 | 75 | [9. Palindrome Number](https://github.com/BaymaxTong/LintCode-Java/tree/master/LeetCode/9.%20Palindrome%20Number.md) 76 | 77 | 78 | 79 | [13. Roman to Integer](https://github.com/BaymaxTong/LintCode-Java/tree/master/LeetCode/13.%20Roman%20to%20Integer.md) 80 | 81 | [14. Longest Common Prefix](https://github.com/BaymaxTong/LintCode-Java/tree/master/LeetCode/14.%20Longest%20Common%20Prefix.md) 82 | 83 | 84 | 85 | 86 | [20. Valid Parentheses](https://github.com/BaymaxTong/LintCode-Java/tree/master/LeetCode/20.%20Valid%20Parentheses.md) 87 | 88 | [21. Merge Two Sorted Lists](https://github.com/BaymaxTong/LintCode-Java/tree/master/LeetCode/21.%20Merge%20Two%20Sorted%20Lists.md) 89 | 90 | 91 | [26. Remove Duplicates from Sorted Array](https://github.com/BaymaxTong/LintCode-Java/tree/master/LeetCode/26.%20Remove%20Duplicates%20from%20Sorted%20Array.md) 92 | 93 | [27. Remove Element](https://github.com/BaymaxTong/LintCode-Java/tree/master/LeetCode/27.%20Remove%20Element.md) 94 | 95 | [28. Implement strStr()](https://github.com/BaymaxTong/LintCode-Java/tree/master/LeetCode/28.%20Implement%20strStr().md) 96 | 97 | 98 | [35. Search Insert Position](https://github.com/BaymaxTong/LintCode-Java/tree/master/LeetCode/35.%20Search%20Insert%20Position.md) 99 | 100 | [38. Count and Say](https://github.com/BaymaxTong/LintCode-Java/tree/master/LeetCode/38.%20Count%20and%20Say.md) 101 | -------------------------------------------------------------------------------- /Remove Linked List Elements: -------------------------------------------------------------------------------- 1 | Remove Linked List Elements 2 | 3 | Remove all elements from a linked list of integers that have value val. 4 | 5 | 样例 6 | Given 1->2->3->3->4->5->3, val = 3, you should return the list as 1->2->4->5 7 | 8 | /** 9 | * Definition for singly-linked list. 10 | * public class ListNode { 11 | * int val; 12 | * ListNode next; 13 | * ListNode(int x) { val = x; } 14 | * } 15 | */ 16 | public class Solution { 17 | /** 18 | * @param head a ListNode 19 | * @param val an integer 20 | * @return a ListNode 21 | */ 22 | public ListNode removeElements(ListNode head, int val) { 23 | // Write your code here 24 | ListNode dummy = new ListNode(0); 25 | dummy.next = head; 26 | head = dummy; 27 | 28 | while (head.next != null) { 29 | if (head.next.val == val) { 30 | head.next = head.next.next; 31 | } else { 32 | head = head.next; 33 | } 34 | } 35 | return dummy.next; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /不同的路径 II--unique-paths-ii: -------------------------------------------------------------------------------- 1 | 不同的路径 II 2 | 跟进“不同的路径”: 3 | 4 | 现在考虑网格中有障碍物,那样将会有多少条不同的路径? 5 | 6 | 网格中的障碍和空位置分别用1和0来表示。 7 | 8 | 样例 9 | 如下所示在3x3的网格中有一个障碍物: 10 | 11 | [ 12 | 13 | [0,0,0], 14 | 15 | [0,1,0], 16 | 17 | [0,0,0] 18 | 19 | ] 20 | 21 | 一共有2条不同的路径从左上角到右下角。 22 | 注意 23 | m和n均不超过100 24 | 25 | public class Solution { 26 | /** 27 | * @param obstacleGrid: A list of lists of integers 28 | * @return: An integer 29 | */ 30 | public int uniquePathsWithObstacles(int[][] obstacleGrid) { 31 | // write your code here 32 | if(obstacleGrid == null || obstacleGrid.length == 0 || obstacleGrid[0].length == 0){ 33 | return 0; 34 | } 35 | int m = obstacleGrid.length; //行 36 | int n = obstacleGrid[0].length; //列 37 | int paths[][] = new int[m][n]; 38 | 39 | for(int i = 0;i < m;i++){ 40 | if(obstacleGrid[i][0] != 1){ 41 | paths[i][0] = 1; 42 | }else{ 43 | break; 44 | } 45 | } 46 | 47 | for(int i = 0;i < n;i++){ 48 | if(obstacleGrid[0][i] != 1){ 49 | paths[0][i] = 1; 50 | }else{ 51 | break; 52 | } 53 | } 54 | 55 | for(int i = 1;i < m;i++){ 56 | for(int j = 1;j < n;j++){ 57 | if(obstacleGrid[i][j] != 1){ 58 | paths[i][j] = paths[i-1][j]+ paths[i][j-1]; 59 | }else{ 60 | paths[i][j] = 0; 61 | } 62 | } 63 | } 64 | return paths[m-1][n-1]; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /主元素--majority-number: -------------------------------------------------------------------------------- 1 | 给定一个整型数组,找出主元素,它在数组中的出现次数严格大于数组元素个数的二分之一。 2 | 样例 3 | 给出数组[1,1,1,1,2,2,2],返回 1 4 | 5 | 挑战 6 | 要求时间复杂度为O(n),空间复杂度为O(1) 7 | 8 | public class Solution { 9 | /** 10 | * @param nums: a list of integers 11 | * @return: find a majority number 12 | */ 13 | public int majorityNumber(ArrayList nums) { 14 | int count = 0,target = -1; 15 | for(int i = 0;i < nums.size();i++){ 16 | if(count == 0){ 17 | target = nums.get(i); 18 | count = 1; 19 | }else if(target == nums.get(i)){ 20 | count ++; 21 | }else{ 22 | count --; 23 | } 24 | } 25 | return target; 26 | } 27 | } 28 | 29 | -------------------------------------------------------------------------------- /二分查找--binary-search: -------------------------------------------------------------------------------- 1 | 二分查找 2 | 给定一个排序的整数数组(升序)和一个要查找的整数target,用O(logn)的时间查找到target第一次出现的下标(从0开始), 3 | 如果target不存在于数组中,返回-1。 4 | 5 | 样例 6 | 在数组 [1, 2, 3, 3, 4, 5, 10] 中二分查找3,返回2。 7 | 8 | 挑战 9 | 如果数组中的整数个数超过了2^32,你的算法是否会出错? 10 | 11 | class Solution { 12 | /** 13 | * @param nums: The integer array. 14 | * @param target: Target to find. 15 | * @return: The first position of target. Position starts from 0. 16 | */ 17 | public int binarySearch(int[] nums, int target) { 18 | if(nums == null||nums.length ==0){ 19 | return -1; 20 | } 21 | int start = 0,end = nums.length -1; 22 | while(start+1 nums[mid]){ 25 | start = mid; 26 | }else{ 27 | end = mid; 28 | } 29 | } 30 | if(nums[start] == target){ 31 | return start; 32 | } 33 | if(nums[end] == target){ 34 | return end; 35 | } 36 | return -1; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /二叉树的中序遍历--binary-tree-inorder-traversal: -------------------------------------------------------------------------------- 1 | 二叉树的中序遍历 2 | 给出一棵二叉树,返回其中序遍历 3 | 4 | 样例 5 | 给出二叉树 {1,#,2,3}, 6 | 7 | 1 8 | \ 9 | 2 10 | / 11 | 3 12 | 返回 [1,3,2]. 13 | 14 | 挑战 15 | 你能使用非递归算法来实现么? 16 | 17 | /** 18 | * Definition of TreeNode: 19 | * public class TreeNode { 20 | * public int val; 21 | * public TreeNode left, right; 22 | * public TreeNode(int val) { 23 | * this.val = val; 24 | * this.left = this.right = null; 25 | * } 26 | * } 27 | */ 28 | public class Solution { 29 | /** 30 | * @param root: The root of binary tree. 31 | * @return: Inorder in ArrayList which contains node values. 32 | */ 33 | public ArrayList inorderTraversal(TreeNode root) { 34 | //递归实现 35 | // ArrayList list = new ArrayList(); 36 | // if(root == null){ 37 | // return list; 38 | // } 39 | // ArrayList left = inorderTraversal(root.left); 40 | // ArrayList right = inorderTraversal(root.right); 41 | // list.addAll(left); 42 | // list.add(root.val); 43 | // list.addAll(right); 44 | // return list; 45 | //非递归实现 46 | Stack stack = new Stack(); 47 | ArrayList result = new ArrayList(); 48 | TreeNode curt = root; 49 | while (curt != null || !stack.empty()) { 50 | while (curt != null) { 51 | stack.add(curt); 52 | curt = curt.left; 53 | } 54 | //curt = stack.peek(); 55 | curt = stack.pop(); 56 | result.add(curt.val); 57 | curt = curt.right; 58 | } 59 | return result; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /二叉树的前序遍历--binary-tree-preorder-traversal: -------------------------------------------------------------------------------- 1 | 二叉树的前序遍历 2 | 给出一棵二叉树,返回其节点值的前序遍历。 3 | 样例 4 | 给出一棵二叉树 {1,#,2,3}, 5 | 6 | 1 7 | \ 8 | 2 9 | / 10 | 3 11 | 返回 [1,2,3]. 12 | 13 | 挑战 14 | 你能使用非递归实现么? 15 | 16 | /** 17 | * Definition of TreeNode: 18 | * public class TreeNode { 19 | * public int val; 20 | * public TreeNode left, right; 21 | * public TreeNode(int val) { 22 | * this.val = val; 23 | * this.left = this.right = null; 24 | * } 25 | * } 26 | */ 27 | public class Solution { 28 | /** 29 | * @param root: The root of binary tree. 30 | * @return: Preorder in ArrayList which contains node values. 31 | */ 32 | public ArrayList preorderTraversal(TreeNode root) { 33 | //递归实现 34 | // ArrayList list = new ArrayList(); 35 | // if(root == null){ 36 | // return list; 37 | // } 38 | // ArrayList left = preorderTraversal(root.left); 39 | // ArrayList right = preorderTraversal(root.right); 40 | // list.add(root.val); 41 | // list.addAll(left); 42 | // list.addAll(right); 43 | // return list; 44 | //非递归实现 45 | Stack stack = new Stack(); 46 | ArrayList list = new ArrayList(); 47 | if(root == null){ 48 | return list; 49 | } 50 | stack.push(root); 51 | while(!stack.empty()){ 52 | TreeNode node = stack.pop(); 53 | list.add(node.val); 54 | if(node.right != null){ 55 | stack.push(node.right); 56 | } 57 | if(node.left != null){ 58 | stack.push(node.left); 59 | } 60 | } 61 | return list; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /二叉树的后序遍历--binary-tree-postorder-traversal: -------------------------------------------------------------------------------- 1 | 二叉树的后序遍历 2 | 给出一棵二叉树,返回其节点值的后序遍历。 3 | 样例 4 | 给出一棵二叉树 {1,#,2,3}, 5 | 6 | 1 7 | \ 8 | 2 9 | / 10 | 3 11 | 返回 [3,2,1] 12 | 13 | 挑战 14 | 你能使用非递归实现么? 15 | 16 | /** 17 | * Definition of TreeNode: 18 | * public class TreeNode { 19 | * public int val; 20 | * public TreeNode left, right; 21 | * public TreeNode(int val) { 22 | * this.val = val; 23 | * this.left = this.right = null; 24 | * } 25 | * } 26 | */ 27 | public class Solution { 28 | /** 29 | * @param root: The root of binary tree. 30 | * @return: Postorder in ArrayList which contains node values. 31 | */ 32 | public ArrayList postorderTraversal(TreeNode root) { 33 | //递归实现 34 | // ArrayList list = new ArrayList(); 35 | // if(root == null){ 36 | // return list; 37 | // } 38 | // ArrayList left = postorderTraversal(root.left); 39 | // ArrayList right = postorderTraversal(root.right); 40 | // list.addAll(left); 41 | // list.addAll(right); 42 | // list.add(root.val); 43 | // return list; 44 | //非递归实现 45 | ArrayList result = new ArrayList(); 46 | Stack stack = new Stack(); 47 | TreeNode prev = null; // previously traversed node 48 | TreeNode curr = root; 49 | 50 | if (root == null) { 51 | return result; 52 | } 53 | 54 | stack.push(root); 55 | while (!stack.empty()) { 56 | curr = stack.peek(); 57 | if (prev == null || prev.left == curr || prev.right == curr) { // traverse down the tree 58 | if (curr.left != null) { 59 | stack.push(curr.left); 60 | } else if (curr.right != null) { 61 | stack.push(curr.right); 62 | } 63 | } else if (curr.left == prev) { // traverse up the tree from the left 64 | if (curr.right != null) { 65 | stack.push(curr.right); 66 | } 67 | } else { // traverse up the tree from the right 68 | result.add(curr.val); 69 | stack.pop(); 70 | } 71 | prev = curr; 72 | } 73 | 74 | return result; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /二叉树的最大深度--maximum-depth-of-binary-tree: -------------------------------------------------------------------------------- 1 | 二叉树的最大深度 2 | 给定一个二叉树,找出其最大深度。 3 | 4 | 二叉树的深度为根节点到最远叶子节点的距离。 5 | 6 | 样例 7 | 给出一棵如下的二叉树: 8 | 9 | 1 10 | / \ 11 | 2 3 12 | / \ 13 | 4 5 14 | 这个二叉树的最大深度为3. 15 | 16 | /** 17 | * Definition of TreeNode: 18 | * public class TreeNode { 19 | * public int val; 20 | * public TreeNode left, right; 21 | * public TreeNode(int val) { 22 | * this.val = val; 23 | * this.left = this.right = null; 24 | * } 25 | * } 26 | */ 27 | public class Solution { 28 | /** 29 | * @param root: The root of binary tree. 30 | * @return: An integer. 31 | */ 32 | public int maxDepth(TreeNode root) { 33 | // write your code here 34 | if(root == null){ 35 | return 0; 36 | } 37 | return Math.max(maxDepth(root.left)+1, maxDepth(root.right)+1); 38 | } 39 | } 40 | 41 | // version 2: Traverse 42 | 43 | /** 44 | * Definition of TreeNode: 45 | * public class TreeNode { 46 | * public int val; 47 | * public TreeNode left, right; 48 | * public TreeNode(int val) { 49 | * this.val = val; 50 | * this.left = this.right = null; 51 | * } 52 | * } 53 | */ 54 | /* 55 | public class Solution { 56 | /** 57 | * @param root: The root of binary tree. 58 | * @return: An integer. 59 | */ 60 | /* private int depth; 61 | 62 | public int maxDepth(TreeNode root) { 63 | depth = 0; 64 | helper(root, 1); 65 | 66 | return depth; 67 | } 68 | 69 | private void helper(TreeNode node, int curtDepth) { 70 | if (node == null) { 71 | return; 72 | } 73 | 74 | if (curtDepth > depth) { 75 | depth = curtDepth; 76 | } 77 | 78 | helper(node.left, curtDepth + 1); 79 | helper(node.right, curtDepth + 1); 80 | } 81 | } 82 | */ 83 | -------------------------------------------------------------------------------- /二进制中有多少个1--count-1-in-binary: -------------------------------------------------------------------------------- 1 | 二进制中有多少个1 2 | 3 | 计算在一个 32 位的整数的二进制表式中有多少个 1. 4 | 5 | 样例 6 | 给定 32 (100000),返回 1 7 | 8 | 给定 5 (101),返回 2 9 | 10 | 给定 1023 (111111111),返回 9 11 | 12 | 13 | public class Solution { 14 | /** 15 | * @param num: an integer 16 | * @return: an integer, the number of ones in num 17 | */ 18 | public int countOnes(int num) { 19 | // write your code here 20 | int sum = 0; 21 | while(num != 0){ 22 | sum += 1; 23 | num = num & (num - 1); 24 | } 25 | return sum; 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /合并排序数组 II--merge-sorted-array: -------------------------------------------------------------------------------- 1 | 合并排序数组 II 2 | 合并两个排序的整数数组A和B变成一个新的数组。 3 | 4 | 样例 5 | 给出A = [1, 2, 3, empty, empty] B = [4,5] 6 | 7 | 合并之后A将变成[1,2,3,4,5] 8 | 9 | 注意 10 | 你可以假设A具有足够的空间(A数组的大小大于或等于m+n)去添加B中的元素。 11 | 12 | class Solution { 13 | /** 14 | * @param A: sorted integer array A which has m elements, 15 | * but size of A is m+n 16 | * @param B: sorted integer array B which has n elements 17 | * @return: void 18 | */ 19 | public void mergeSortedArray(int[] A, int m, int[] B, int n) { 20 | //已经排序的整数数组 21 | int i = m-1, j = n-1,index = m+n-1; 22 | while(i >= 0 && j>= 0){ 23 | if(A[i] > B[j]){ 24 | A[index--] = A[i--]; 25 | }else{ 26 | A[index--] = B[j--]; 27 | } 28 | } 29 | while(i >= 0){ 30 | A[index--] = A[i--]; 31 | } 32 | while(j >= 0){ 33 | A[index--] = B[j--]; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /合并排序数组--merge-sorted-array-ii: -------------------------------------------------------------------------------- 1 | 合并两个排序的整数数组A和B变成一个新的数组。 2 | 样例 3 | 给出A=[1,2,3,4],B=[2,4,5,6],返回 [1,2,2,3,4,4,5,6] 4 | 5 | class Solution { 6 | /** 7 | * @param A and B: sorted integer array A and B. 8 | * @return: A new sorted integer array 9 | */ 10 | public ArrayList mergeSortedArray(ArrayList A, ArrayList B) { 11 | int len = B.size(); 12 | for(int i =0 ;i< len;i++){ 13 | A.add(B.get(i)); 14 | } 15 | Collections.sort(A); 16 | return A; 17 | } 18 | } 19 | //method 2 20 | class Solution { 21 | /** 22 | * @param A and B: sorted integer array A and B. 23 | * @return: A new sorted integer array 24 | */ 25 | public ArrayList mergeSortedArray(ArrayList A, ArrayList B) { 26 | A.addAll(B); 27 | Collections.sort(A); 28 | return A; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /在二叉查找树中插入节点--insert-node-in-a-binary-search-tree: -------------------------------------------------------------------------------- 1 | 在二叉查找树中插入节点 2 | 给定一棵二叉查找树和一个新的树节点,将节点插入到树中。 3 | 4 | 你需要保证该树仍然是一棵二叉查找树。 5 | 6 | 样例 7 | 给出如下一棵二叉查找树,在插入节点6之后这棵二叉查找树可以是这样的: 8 | 9 | 2 2 10 | / \ / \ 11 | 1 4 --> 1 4 12 | / / \ 13 | 3 3 6 14 | 挑战 15 | 能否不使用递归? 16 | 17 | /** 18 | * Definition of TreeNode: 19 | * public class TreeNode { 20 | * public int val; 21 | * public TreeNode left, right; 22 | * public TreeNode(int val) { 23 | * this.val = val; 24 | * this.left = this.right = null; 25 | * } 26 | * } 27 | */ 28 | public class Solution { 29 | /** 30 | * @param root: The root of the binary search tree. 31 | * @param node: insert this node into the binary search tree 32 | * @return: The root of the new binary search tree. 33 | */ 34 | public TreeNode insertNode(TreeNode root, TreeNode node) { 35 | // write your code here 36 | if(root == null){ 37 | return node; 38 | } 39 | TreeNode curt = root; 40 | while(curt != node){ 41 | if(node.val < curt.val){ 42 | if(curt.left == null){ 43 | curt.left = node; 44 | } 45 | curt = curt.left; 46 | }else{ 47 | if(curt.right == null){ 48 | curt.right = node; 49 | } 50 | curt = curt.right; 51 | } 52 | } 53 | return root; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /字符串查找--strstr: -------------------------------------------------------------------------------- 1 | 字符串查找(又称查找子字符串),是字符串操作中一个很有用的函数。你的任务是实现这个函数。 2 | 3 | 对于一个给定的 source 字符串和一个 target 字符串,你应该在 source 字符串中找出 target 字符串出现的第一个位置(从0开始)。 4 | 5 | 如果不存在,则返回 -1。 6 | 7 | 样例 8 | 如果 source = "source" 和 target = "target",返回 -1。 9 | 10 | 如果 source = "abcdabcdefg" 和 target = "bcd",返回 1。 11 | 12 | 挑战 13 | O(n2)的算法是可以接受的。如果你能用O(n)的算法做出来那更加好。(提示:KMP) 14 | 15 | class Solution { 16 | /** 17 | * Returns a index to the first occurrence of target in source, 18 | * or -1 if target is not part of source. 19 | * @param source string to be scanned. 20 | * @param target string containing the sequence of characters to match. 21 | */ 22 | public int strStr(String source, String target) { 23 | if(source == null||target == null){ 24 | return -1; 25 | } 26 | int i,j; 27 | for(i = 0;i= 1;i *= 5){ 18 | num +=n/i; 19 | } 20 | return num; 21 | } 22 | 23 | }; 24 | -------------------------------------------------------------------------------- /恢复旋转排序数组--recover-rotated-sorted-array: -------------------------------------------------------------------------------- 1 | 恢复旋转排序数组 2 | 给定一个旋转排序数组,在原地恢复其排序。 3 | 样例 4 | [4, 5, 1, 2, 3] -> [1, 2, 3, 4, 5] 5 | 6 | 挑战 7 | 使用O(1)的额外空间和O(n)时间复杂度 8 | 9 | public class Solution { 10 | /** 11 | * @param nums: The rotated sorted array 12 | * @return: void 13 | */ 14 | public ArrayList recoverRotatedSortedArray(ArrayList nums) { 15 | //Collections.sort(nums); 16 | int offset = 0; 17 | for(int i = 0;i < nums.size()-1;i++){ 18 | if(nums.get(i) > nums.get(i+1)){ 19 | offset = i+1; 20 | break; 21 | } 22 | } 23 | if(offset == 0){ 24 | return nums; 25 | }else{ 26 | for(int i = 0;i < offset;i++){ 27 | int temp = nums.get(0); 28 | nums.remove(0); 29 | nums.add(temp); 30 | } 31 | } 32 | return nums; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /插入区间--insert-interval: -------------------------------------------------------------------------------- 1 | 插入区间 2 | 给出一个无重叠的按照区间起始端点排序的区间列表。 3 | 在列表中插入一个新的区间,你要确保列表中的区间仍然有序且不重叠(如果有必要的话,可以合并区间)。 4 | 5 | 样例 6 | 插入区间[2, 5] 到 [[1,2], [5,9]],我们得到 [[1,9]]。 7 | 8 | 插入区间[3, 4] 到 [[1,2], [5,9]],我们得到 [[1,2], [3,4], [5,9]]。 9 | 10 | /** 11 | * Definition of Interval: 12 | * public classs Interval { 13 | * int start, end; 14 | * Interval(int start, int end) { 15 | * this.start = start; 16 | * this.end = end; 17 | * } 18 | */ 19 | 20 | class Solution { 21 | /** 22 | * Insert newInterval into intervals. 23 | * @param intervals: Sorted interval list. 24 | * @param newInterval: A new interval. 25 | * @return: A new sorted interval list. 26 | */ 27 | public ArrayList insert(ArrayList intervals, Interval newInterval) { 28 | ArrayList result = new ArrayList(); 29 | for(Interval interval:intervals){ 30 | if(interval.end < newInterval.start){ 31 | result.add(interval); 32 | }else if(interval .start > newInterval.end){ 33 | result.add(newInterval); 34 | newInterval = interval; 35 | }else{ 36 | newInterval = new Interval(Math.min(interval .start,newInterval.start),Math.max(interval.end,newInterval.end)); 37 | } 38 | } 39 | result.add(newInterval); 40 | return result; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /搜索二维矩阵--search-a-2d-matrix: -------------------------------------------------------------------------------- 1 | 搜索二维矩阵 2 | 写出一个高效的算法来搜索 m × n矩阵中的值。 3 | 4 | 这个矩阵具有以下特性: 5 | 6 | 每行中的整数从左到右是排序的。 7 | 每行的第一个数大于上一行的最后一个整数。 8 | 9 | 样例 10 | 考虑下列矩阵: 11 | 12 | [ 13 | [1, 3, 5, 7], 14 | [10, 11, 16, 20], 15 | [23, 30, 34, 50] 16 | ] 17 | 给出 target = 3,返回 true 18 | 19 | 挑战 20 | O(log(n) + log(m)) 时间复杂度 21 | 22 | public class Solution { 23 | /** 24 | * @param matrix, a list of lists of integers 25 | * @param target, an integer 26 | * @return a boolean, indicate whether matrix contains target 27 | */ 28 | public boolean searchMatrix(int[][] matrix, int target) { 29 | if(matrix == null ||matrix.length == 0){ 30 | return false; 31 | } 32 | int m = matrix.length ,n = matrix[0].length; 33 | for(int i = 0;i < m;i++){ 34 | if(matrix[i][n-1] >= target){ 35 | for(int j =0;j= target){ 37 | return start; 38 | }else if(A[end] >= target){ 39 | return end; 40 | }else{ 41 | return end+1; 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /数组剔除元素后的乘积--product-of-array-exclude-itself: -------------------------------------------------------------------------------- 1 | 数组剔除元素后的乘积 2 | 3 | 给定一个整数数组A。 4 | 定义B[i] = A[0] * ... * A[i-1] * A[i+1] * ... * A[n-1], 计算B的时候请不要使用除法。 5 | 6 | 样例 7 | 给出A=[1, 2, 3],返回 B为[6, 3, 2] 8 | 9 | public class Solution { 10 | /** 11 | * @param A: Given an integers array A 12 | * @return: A Long array B and B[i]= A[0] * ... * A[i-1] * A[i+1] * ... * A[n-1] 13 | */ 14 | public ArrayList productExcludeItself(ArrayList A) { 15 | ArrayList B = new ArrayList(); 16 | for(int i = 0;i < A.size();i++){ 17 | long temp = 1; 18 | for(int j = 0;j < A.size();j++){ 19 | if(i != j){ 20 | temp *= A.get(j); 21 | } 22 | } 23 | B.add(temp); 24 | } 25 | return B; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /斐波纳契数列--fibonacci: -------------------------------------------------------------------------------- 1 | 斐波纳契数列 2 | 查找斐波纳契数列中第 N 个数。 3 | 4 | 所谓的斐波纳契数列是指: 5 | 6 | 前2个数是 0 和 1 。 7 | 第 i 个数是第 i-1 个数和第i-2 个数的和。 8 | 斐波纳契数列的前10个数字是: 9 | 10 | 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 ... 11 | 12 | 样例 13 | 给定 1,返回 0 14 | 15 | 给定 2,返回 1 16 | 17 | 给定 10,返回 34 18 | 19 | class Solution { 20 | /** 21 | * @param n: an integer 22 | * @return an integer f(n) 23 | */ 24 | public int fibonacci(int n) { 25 | if(n == 1){ 26 | return 0; 27 | }else if(n == 2){ 28 | return 1; 29 | }else{ 30 | //return fibonacci(n-1)+fibonacci(n-2); 31 | int a[] = new int[n]; 32 | a[0] = 0; 33 | a[1] = 1; 34 | for(int i = 3;i <= n;i++){ 35 | a[i-1] = a[i-2] + a[i-3]; 36 | } 37 | return a[n-1]; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /旋转字符串--rotate-string: -------------------------------------------------------------------------------- 1 | 给定一个字符串和一个偏移量,根据偏移量旋转字符串(从左向右旋转) 2 | 样例 3 | 对于字符串 "abcdefg". 4 | 5 | offset=0 => "abcdefg" 6 | offset=1 => "gabcdef" 7 | offset=2 => "fgabcde" 8 | offset=3 => "efgabcd" 9 | 10 | 挑战 11 | 在数组上原地旋转,使用O(1)的额外空间 12 | 13 | public class Solution { 14 | /** 15 | * @param str: an array of char 16 | * @param offset: an integer 17 | * @return: nothing 18 | */ 19 | public char[] rotateString(char[] A, int offset) { 20 | if (A == null || A.length == 0) { 21 | return A; 22 | } 23 | offset = offset % A.length; 24 | reverse(A, 0, A.length - offset - 1); 25 | reverse(A, A.length - offset, A.length - 1); 26 | reverse(A, 0, A.length - 1); 27 | return A; 28 | } 29 | 30 | private void reverse(char[] A, int start, int end) { 31 | for (int i = start, j = end; i < j; i++, j--) { 32 | char temp = A[i]; 33 | A[i] = A[j]; 34 | A[j] = temp; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /最大子数组--maximum-subarray: -------------------------------------------------------------------------------- 1 | 最大子数组 2 | 3 | 给定一个整数数组,找到一个具有最大和的子数组,返回其最大和。 4 | 5 | 样例 6 | 给出数组[−2,2,−3,4,−1,2,1,−5,3],符合要求的子数组为[4,−1,2,1],其最大和为6 7 | 8 | 注意 9 | 子数组最少包含一个数 10 | 11 | 挑战 12 | 要求时间复杂度为O(n) 13 | 14 | public class Solution { 15 | /** 16 | * @param nums: A list of integers 17 | * @return: A integer indicate the sum of max subarray 18 | */ 19 | public int maxSubArray(ArrayList nums) { 20 | int sum = nums.get(0),temp = 0; 21 | for(int i = 0; i < nums.size(); i++){ 22 | temp += nums.get(i); 23 | if(temp <= 0){ 24 | //sum = 0; 25 | temp = 0; 26 | }else if(temp > sum){ 27 | sum = temp; 28 | } 29 | } 30 | return sum; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /最小子数组--minimum-subarray: -------------------------------------------------------------------------------- 1 | 最小子数组 2 | 给定一个整数数组,找到一个具有最小和的子数组。返回其最小和。 3 | 4 | 样例 5 | 给出数组[1, -1, -2, 1],返回 -3 6 | 7 | 注意 8 | 子数组最少包含一个数字 9 | 10 | public class Solution { 11 | /** 12 | * @param nums: a list of integers 13 | * @return: A integer indicate the sum of minimum subarray 14 | */ 15 | public int minSubArray(ArrayList nums) { 16 | int min = Integer.MAX_VALUE, sum = 0; 17 | for(int i = 0; i < nums.size();i++){ 18 | sum += nums.get(i); 19 | sum = Math.min(sum,nums.get(i)); 20 | min = Math.min(sum,min); 21 | } 22 | return min; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /比较字符串--compare-strings: -------------------------------------------------------------------------------- 1 | 比较字符串 2 | 比较两个字符串A和B,确定A中是否包含B中所有的字符。字符串A和B中的字符都是 大写字母 3 | 4 | 样例 5 | 给出 A = "ABCD" B = "ACD",返回 true 6 | 7 | 给出 A = "ABCD" B = "AABC", 返回 false 8 | 9 | public class Solution { 10 | /** 11 | * @param A : A string includes Upper Case letters 12 | * @param B : A string includes Upper Case letter 13 | * @return : if string A contains all of the characters in B return true else return false 14 | */ 15 | public boolean compareStrings(String A, String B) { 16 | if(B.length() > A.length()){ 17 | return false; 18 | } 19 | char[] aChar = A.toCharArray(); 20 | int n = B.length(); 21 | for(int i = 0;i < B.length();i++){ 22 | for(int j = 0;j < A.length();j++){ 23 | if(aChar[j] == B.charAt(i)){ 24 | aChar[j] = ' '; 25 | --n; 26 | break; 27 | } 28 | } 29 | } 30 | if(n == 0){ 31 | return true; 32 | }else{ 33 | return false; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /矩阵的之字型遍历--matrix-zigzag-traversal: -------------------------------------------------------------------------------- 1 | 矩阵的之字型遍历 2 | 给你一个包含 m x n 个元素的矩阵 (m 行, n 列), 求该矩阵的之字型遍历。 3 | 样例 4 | 对于如下矩阵: 5 | 6 | [ 7 | [1, 2, 3, 4], 8 | [5, 6, 7, 8], 9 | [9,10, 11, 12] 10 | ] 11 | 返回 [1, 2, 5, 9, 6, 3, 4, 7, 10, 11, 8, 12] 12 | 13 | public class Solution { 14 | /** 15 | * @param matrix: a matrix of integers 16 | * @return: an array of integers 17 | */ 18 | public int[] printZMatrix(int[][] matrix) { 19 | if(matrix ==null ||matrix.length ==0 ||matrix[0]==null ||matrix[0].length ==0){ 20 | return null; 21 | } 22 | 23 | int count = matrix.length * matrix[0].length; 24 | int[] array = new int[count]; 25 | int r = 0, c = 0; 26 | array[0] = matrix[0][0]; 27 | int i = 1; 28 | while (i < count) { 29 | //斜上走到顶 30 | while(r - 1 >= 0 && c + 1 < matrix[0].length) { 31 | array[i++] = matrix[--r][++c]; 32 | } 33 | //横右走一步,不可横右走时竖下走一步 34 | if (c + 1 < matrix[0].length) { 35 | array[i++] = matrix[r][++c]; 36 | } else if (i < count && r + 1 < matrix.length) { 37 | array[i++] = matrix[++r][c]; 38 | } 39 | //斜下走到底 40 | while(r + 1 < matrix.length && c - 1 >= 0) { 41 | array[i++] = matrix[++r][--c]; 42 | } 43 | //竖下走一步,不可竖下走时横右走一步 44 | if (r + 1 < matrix.length) { 45 | array[i++] = matrix[++r][c]; 46 | } else if (c + 1 < matrix[0].length) { 47 | array[i++] = matrix[r][++c]; 48 | } 49 | } 50 | return array; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /翻转字符串--reverse-words-in-a-string: -------------------------------------------------------------------------------- 1 | 翻转字符串 2 | 3 | 给定一个字符串,逐个翻转字符串中的每个单词。 4 | 样例 5 | 给出s = "the sky is blue",返回"blue is sky the" 6 | 7 | 说明 8 | 单词的构成:无空格字母构成一个单词 9 | 输入字符串是否包括前导或者尾随空格?可以包括,但是反转后的字符不能包括 10 | 如何处理两个单词间的多个空格?在反转字符串中间空格减少到只含一个 11 | 12 | public class Solution { 13 | /** 14 | * @param s : A string 15 | * @return : A string 16 | */ 17 | public String reverseWords(String s) { 18 | if (s == null || s.length() == 0) { 19 | return ""; 20 | } 21 | 22 | String[] array = s.split(" "); 23 | StringBuilder sb = new StringBuilder(); 24 | 25 | for (int i = array.length - 1; i >= 0; --i) { 26 | if (!array[i].equals("")) { 27 | sb.append(array[i]).append(" "); 28 | } 29 | } 30 | 31 | //remove the last " " 32 | return sb.length() == 0 ? "" : sb.substring(0, sb.length() - 1); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /翻转链表--reverse-linked-list: -------------------------------------------------------------------------------- 1 | 翻转链表 2 | 翻转一个链表 3 | 样例 4 | 给出一个链表1->2->3->null,这个翻转后的链表为3->2->1->null 5 | 6 | 挑战 7 | 在原地一次翻转完成 8 | 9 | /** 10 | * Definition for ListNode. 11 | * public class ListNode { 12 | * int val; 13 | * ListNode next; 14 | * ListNode(int val) { 15 | * this.val = val; 16 | * this.next = null; 17 | * } 18 | * } 19 | */ 20 | public class Solution { 21 | /** 22 | * @param head: The head of linked list. 23 | * @return: The new head of reversed linked list. 24 | */ 25 | public ListNode reverse(ListNode head) { 26 | ListNode prev = null; 27 | while (head != null) { 28 | ListNode temp = head.next; 29 | head.next = prev; 30 | prev = head; 31 | head = temp; 32 | } 33 | return prev; 34 | 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /落单的数--single-number: -------------------------------------------------------------------------------- 1 | 落单的数 2 | 3 | 给出2*n + 1 个的数字,除其中一个数字之外其他每个数字均出现两次,找到这个数字。 4 | 5 | 样例 6 | 给出 [1,2,2,1,3,4,3],返回 4 7 | 8 | 挑战 9 | 一次遍历,常数级的额外空间复杂度 10 | 11 | public class Solution { 12 | /** 13 | *@param A : an integer array 14 | *return : a integer 15 | */ 16 | public int singleNumber(int[] A) { 17 | if(A == null||A.length == 0){ 18 | return 0; 19 | } 20 | int n = A[0]; 21 | for(int i = 1;i < A.length;i++){ 22 | n = n ^ A[i]; 23 | } 24 | return n; 25 | } 26 | } 27 | --------------------------------------------------------------------------------