牛客研发最爱考、剑指offer经典题目
字符串 进制转换 题目链接
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 import java.util.*;public class Solution { public String solve (int M, int N) { if (M == 0 ){ return "0" ; } String s = "0123456789ABCDEF" ; boolean f = false ; if (M < 0 ){ f = true ; M = -M; } StringBuilder sb = new StringBuilder(); while (M != 0 ){ sb.append(s.charAt(M%N)); M /= N; } if (f){ sb.append("-" ); } return sb.reverse().toString(); } }
字符串解码 题目链接
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 class Solution { public String decodeString (String s) { char [] chars = s.toCharArray(); Deque<Integer> stackNum = new ArrayDeque<>(); Deque<String> stack = new ArrayDeque<>(); StringBuilder sb = new StringBuilder(); int num = 0 ; for (int i = 0 ; i < chars.length ; i++) { if (chars[i] >= '0' && chars[i] <= '9' ) { num = num * 10 + Integer.parseInt(chars[i] + "" ); } else if (chars[i] == '[' ) { stackNum.addLast(num); stack.addLast(sb.toString()); sb = new StringBuilder(); num = 0 ; } else if (chars[i] == ']' ) { StringBuilder temp = new StringBuilder(); int n = stackNum.removeLast(); while (n > 0 ) { temp.append(sb); n--; } sb = new StringBuilder(stack.removeLast() + temp); } else { sb.append(chars[i]); } } return sb.toString(); } }
数组 数组中未出现的最小正整数 题目链接
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 public class Solution { public int minNumberdisappered (int [] arr) { if (arr == null ){ return 1 ; } int min = arr[0 ]; int max = arr[0 ]; int sum1 = arr[0 ]; for (int i = 1 ; i < arr.length; i++){ min = Math.min(min,arr[i]); max = Math.max(max,arr[i]); sum1 += arr[i]; } int sum2 = 0 ; for (int i = min; i <= max; i++){ sum2 += i; } int num = sum2 - sum1 == 0 ? max + 1 : sum2 - sum1; return Math.max(1 ,num); } }
顺时针旋转矩阵 题目链接
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public class Solution { public int [][] rotateMatrix(int [][] mat, int n) { for (int i = 0 ; i < n / 2 ; i++){ for (int j = 0 ; j < (n+1 ) / 2 ; j++){ int tmp = mat[i][j]; mat[i][j] = mat[n - j - 1 ][i]; mat[n - j - 1 ][i] = mat[n - i - 1 ][n - j - 1 ]; mat[n - i - 1 ][n - j - 1 ] = mat[j][n - i - 1 ]; mat[j][n - i - 1 ] = tmp; } } return mat; } }
重排数组元素,奇数放在奇数位,偶数放在偶数位 题目链接
思路: 找到不符合条件的奇数和偶数进行交换。
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public static void sort (int [] arr) { int i = 0 ; int j = 1 ; int len = arr.length; while (i < len && j < len){ while (i < len && (arr[i] & 1 ) == 0 ) i += 2 ; while (j < len && (arr[j] & 1 ) == 1 ) j += 2 ; if (i < len && j < len) { swap(arr[i], arr[j]); } } }
连续的子数组和 题目链接
思路: 前缀和+HashMap
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class Solution { public boolean checkSubarraySum (int [] nums, int k) { int n = nums.length; if (n < 2 ){ return false ; } Map<Integer,Integer> map = new HashMap(); map.put(0 ,-1 ); int res = 0 ; for (int i = 0 ; i < n; i++){ res = (res + nums[i]) % k; if (map.containsKey(res)){ if (i - map.get(res) >= 2 ){ return true ; } }else { map.put(res,i); } } return false ; } }
连续数组 题目链接
思路: 前缀和+HashMap
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 class Solution { public int findMaxLength (int [] nums) { int maxLen = 0 ; Map<Integer,Integer> map = new HashMap(); int cnt = 0 ; map.put(0 ,-1 ); for (int i = 0 ; i < nums.length; i++){ int num = nums[i]; if (num == 1 ){ cnt++; }else { cnt--; } if (map.containsKey(cnt)){ int pre = map.get(cnt); maxLen = Math.max(maxLen,i-pre); }else { map.put(cnt,i); } } return maxLen; } }
长度最小的子数组 题目链接
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 class Solution { public int minSubArrayLen (int target, int [] nums) { int n = nums.length; if (n == 0 ){ return 0 ; } int start = 0 ; int end = 0 ; int sum = 0 ; int res = Integer.MAX_VALUE; while (end < n){ sum += nums[end]; while (sum >= target){ res = Math.min(res,end - start + 1 ); sum -= nums[start]; start++; } end++; } return res == Integer.MAX_VALUE ? 0 : res; } }
三个数的最大乘积 628. 三个数的最大乘积
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 class Solution { public int maximumProduct (int [] nums) { int max1 = Integer.MIN_VALUE; int max2 = Integer.MIN_VALUE; int max3 = Integer.MIN_VALUE; int min1 = Integer.MAX_VALUE; int min2 = Integer.MAX_VALUE; for (int num : nums){ if (num > max1){ max3 = max2; max2 = max1; max1 = num; }else if (num > max2){ max3 = max2; max2 = num; }else if (num > max3){ max3 = num; } if (num < min1){ min2 = min1; min1 = num; }else if (num < min2){ min2 = num; } } int res = Math.max(max1 * max2 * max3,max1 * min1 * min2); return res; } }
二分查找 在转动过的有序数组中寻找目标值 题目链接
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 import java.util.*;public class Solution { public int search (int [] A, int target) { if (A[0 ] < A[A.length - 1 ]){ return bsearch(A,target,0 ,A.length - 1 ); } int left = 0 ; int right = A.length - 1 ; int mid; while (left <= right){ mid = (left + right) / 2 ; if (A[mid] >= A[0 ]){ left = mid + 1 ; }else { right = mid - 1 ; } } if (target >= A[0 ]){ return bsearch(A,target,0 ,right); }else { return bsearch(A,target,left,A.length - 1 ); } } public int bsearch (int [] A,int target,int left, int right) { int mid; while (left <= right){ mid = (left + right) / 2 ; if (target == A[mid]){ return mid; }else if (target > A[mid]){ left = mid + 1 ; }else { right = mid - 1 ; } } return -1 ; } }
搜索旋转排序数组 题目链接
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 class Solution { public int search (int [] nums, int target) { int n = nums.length; if (nums == null || n == 0 ){ return -1 ; } if (n == 1 ){ return nums[0 ] == target ? 0 : -1 ; } int left = 0 ; int right = n - 1 ; while (left <= right){ int mid = left + (right - left) / 2 ; if (nums[mid] == target){ return mid; } if (nums[0 ] <= nums[mid]){ if (nums[mid] > target && target >= nums[0 ]){ right = mid - 1 ; }else { left = mid + 1 ; } }else { if (nums[mid] < target && target <= nums[n-1 ]){ left = mid + 1 ; }else { right = mid - 1 ; } } } return -1 ; } }
搜索旋转排序数组 II 题目链接
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 class Solution { public boolean search (int [] nums, int target) { if (nums == null || nums.length == 0 ){ return false ; } int start = 0 ; int end = nums.length - 1 ; while (start <= end){ int mid = start + (end - start) / 2 ; if (nums[mid] == target){ return true ; } if (nums[start] == nums[mid]){ start++; continue ; } if (nums[start] < nums[mid]){ if (nums[mid] > target && nums[start] <= target){ end = mid - 1 ; }else { start = mid + 1 ; } }else { if (nums[mid] < target && target <= nums[end]){ start = mid + 1 ; }else { end = mid - 1 ; } } } return false ; } }
寻找旋转排序数组中的最小值 II 题目链接
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class Solution { public int findMin (int [] nums) { int left= 0 ; int right = nums.length - 1 ; while (left <= right){ int mid = left + (right - left) / 2 ; if (nums[mid] == nums[right]){ right--; }else if (nums[mid] < nums[right]){ right = mid; }else { left = mid + 1 ; } } return nums[left]; } }
二分查找-II 题目链接
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public int search (int [] nums, int target) { int low = 0 ; int high = nums.length - 1 ; int mid = 0 ; while (low <= high){ mid = low + (high - low) / 2 ; if (nums[mid] == target){ while (mid != 0 && nums[mid] == nums[mid - 1 ]){ mid--; } return mid; } else if (nums[mid] > target){ high = mid - 1 ; }else { low = mid + 1 ; } } return -1 ; }
双指针 删除排序数组中的重复项 题目链接
代码如下:
1 2 3 4 5 6 7 8 9 10 11 public int removeDuplicates (int [] nums) { if (nums.length == 0 ) return 0 ; int i = 0 ; for (int j = 1 ; j < nums.length; j++) { if (nums[j] != nums[i]) { i++; nums[i] = nums[j]; } } return i + 1 ; }
回文数字 题解
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public class Solution { public boolean isPalindrome (int x) { if (x == 0 ){ return true ; } if (x < 0 || x % 10 == 0 ){ return false ; } int reverse = 0 ; while (x > reverse){ reverse = reverse * 10 + x % 10 ; x /= 10 ; } return (reverse == x) || (reverse / 10 == x); } }
无重复字符的最长子串 3. 无重复字符的最长子串
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class Solution { public int lengthOfLongestSubstring (String s) { int len = s.length(); if (len == 0 ){ return 0 ; } int left = 0 ; int max = 0 ; Map<Character,Integer> map = new HashMap(); for (int i = 0 ; i < len; i++){ char ch = s.charAt(i); if (map.containsKey(ch)){ left = Math.max(left,map.get(ch) + 1 ); } map.put(ch,i); max = Math.max(max,i - left + 1 ); } return max; } }
链表 两个链表生成相加链表
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 import java.util.*;public class Solution { public ListNode addInList (ListNode head1, ListNode head2) { ListNode p1 = reverse(head1); ListNode p2 = reverse(head2); ListNode res = new ListNode(-1 ); ListNode curr = res; int carry = 0 ; while (p1 != null || p2 != null ){ int sum = 0 ; if (p1 != null ){ sum += p1.val; p1 = p1.next; } if (p2 != null ){ sum += p2.val; p2 = p2.next; } sum += carry; curr.next = new ListNode(sum % 10 ); carry = sum / 10 ; curr = curr.next; } if (carry > 0 ){ curr.next = new ListNode(carry); } return reverse(res.next); } public ListNode reverse (ListNode head) { ListNode pre = null ; ListNode next = null ; while (head != null ){ next = head.next; head.next = pre; pre = head; head = next; } return pre; } }
合并k个已排序的链表 题目链接
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 import java.util.*;public class Solution { public ListNode mergeKLists (ArrayList<ListNode> lists) { if (lists == null || lists.size() == 0 ){ return null ; } return mergeKList(lists,0 ,lists.size() - 1 ); } public ListNode mergeKList (ArrayList<ListNode> lists,int low, int high) { if (low >= high){ return lists.get(low); } int mid = low + (high - low) / 2 ; ListNode l1 = mergeKList(lists,low,mid); ListNode l2 = mergeKList(lists,mid + 1 ,high); return merge(l1,l2); } public ListNode merge (ListNode node1,ListNode node2) { ListNode node = new ListNode(-1 ); ListNode tmp = node; while (node1!=null && node2!=null ){ if (node1.val <= node2.val){ tmp.next = node1; node1 = node1.next; }else { tmp.next = node2; node2 = node2.next; } tmp = tmp.next; } tmp.next = node1!=null ?node1:node2; return node.next; } }
单链表的排序 题目链接
代码如下(方法1 归并排序):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 import java.util.*;public class Solution { public ListNode sortInList (ListNode head) { if (head == null || head.next == null ){ return head; } ListNode slow = head; ListNode fast = head.next; while (fast != null && fast.next != null ){ slow = slow.next; fast = fast.next.next; } ListNode newList = slow.next; slow.next = null ; ListNode left = sortInList(head); ListNode right = sortInList(newList); ListNode dummy = new ListNode(-1 ); ListNode res = dummy; while (left != null && right != null ){ if (left.val < right.val){ res.next = left; left = left.next; }else { res.next = right; right = right.next; } res = res.next; } res.next = left == null ? right : left; return dummy.next; } }
代码如下(方法2 插入排序):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 class Solution { public ListNode insertionSortList (ListNode head) { if (head == null ){ return head; } ListNode dummy = new ListNode(0 ); dummy.next = head; ListNode lastSorted = head; ListNode curr = head.next; while (curr != null ){ if (lastSorted.val <= curr.val){ lastSorted = lastSorted.next; }else { ListNode pre = dummy; while (pre.next.val <= curr.val){ pre = pre.next; } lastSorted.next = curr.next; curr.next = pre.next; pre.next = curr; } curr = lastSorted.next; } return dummy.next; } }
链表内指定区间反转 题目链接
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 import java.util.*;public class Solution { public ListNode reverseBetween (ListNode head, int m, int n) { ListNode dummy = new ListNode(-1 ); dummy.next = head; ListNode pre = dummy; for (int i = 0 ; i < m-1 ; i++){ pre = pre.next; } head = pre.next; ListNode next = null ; for (int i = m; i < n; i++){ next = head.next; head.next = next.next; next.next = pre.next; pre.next = next; } return dummy.next; } }
删除有序链表中重复出现的元素(将重复出现的元素删完) 题目链接
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 public class Solution { public ListNode deleteDuplicates (ListNode head) { ListNode dummy = new ListNode(-1 ); dummy.next = head; ListNode pre = dummy; ListNode curr = head; while (curr != null && curr.next != null ){ if (curr.val == curr.next.val){ ListNode tmp = curr.next; while (tmp != null && tmp.val == curr.val){ tmp = tmp.next; } pre.next = tmp; curr = tmp; }else { pre = pre.next; curr = curr.next; } } return dummy.next; } }
删除有序链表中重复的元素(使每个元素只出现一次) 题目链接
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 public class Solution { public ListNode deleteDuplicates (ListNode head) { if (head == null ){ return null ; } ListNode tmp = head; while (tmp.next != null ){ if (tmp.val == tmp.next.val){ tmp.next = tmp.next.next; }else { tmp = tmp.next; } } return head; } }
链表的奇偶重排 题目链接
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 public class Solution { public ListNode oddEvenList (ListNode head) { if (head == null ){ return head; } ListNode evenHead = head.next; ListNode odd = head; ListNode even = evenHead; while (even != null && even.next != null ){ odd.next = even.next; odd = odd.next; even.next = odd.next; even = even.next; } odd.next = evenHead; return head; } }
重排链表 题目链接
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 public class Solution { public void reorderList (ListNode head) { if (head == null || head.next == null || head.next.next == null ) return ; ListNode slow = head; ListNode fast = head.next; while (fast != null && fast.next != null ){ slow = slow.next; fast = fast.next.next; } ListNode newList = slow.next; slow.next = null ; ListNode newHead = reverse(newList); while (newHead != null ){ ListNode temp = newHead.next; newHead.next = head.next; head.next = newHead; head = newHead.next; newHead = temp; } } public ListNode reverse (ListNode head) { ListNode pre = null ; while (head != null ){ ListNode next = head.next; head.next = pre; pre = head; head = next; } return pre; } }
K 个一组翻转链表 题目链接
代码如下: 解法1:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 public ListNode reverseKGroup (ListNode head, int k) { if (head == null || head.next == null ) { return head; } ListNode tail = head; for (int i = 0 ; i < k; i++) { if (tail == null ) { return head; } tail = tail.next; } ListNode newHead = reverse(head, tail); head.next = reverseKGroup(tail, k); return newHead; } private ListNode reverse (ListNode head, ListNode tail) { ListNode pre = null ; ListNode next = null ; while (head != tail) { next = head.next; head.next = pre; pre = head; head = next; } return pre; }
解法2:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 class Solution { public ListNode reverseKGroup (ListNode head, int k) { ListNode dummy = new ListNode(-1 ); dummy.next = head; ListNode pre = dummy; ListNode end = dummy; while (end.next != null ){ for (int i = 0 ; i < k && end != null ; i++){ end = end.next; } if (end == null ){ break ; } ListNode start = pre.next; ListNode next = end.next; end.next = null ; pre.next = reverse(start); start.next = next; pre = start; end = start; } return dummy.next; } public ListNode reverse (ListNode head) { ListNode pre = null ; ListNode curr = head; while (curr != null ){ ListNode next = curr.next; curr.next = pre; pre = curr; curr = next; } return pre; } }
环形链表Ⅱ 题目链接
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 public class Solution { public ListNode detectCycle (ListNode head) { if (head == null ){ return null ; } ListNode slow = head; ListNode fast = head; while (true ){ if (fast == null || fast.next == null ){ return null ; } slow = slow.next; fast = fast.next.next; if (fast == slow){ break ; } } fast = head; while (fast != slow){ fast = fast.next; slow = slow.next; } return fast; } }
两两交换链表中的节点 题目链接
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 class Solution { public ListNode swapPairs (ListNode head) { if (head == null ){ return null ; } if (head.next == null ){ return head; } ListNode dummy = new ListNode(-1 ); dummy.next = head; ListNode pre = dummy; ListNode curr = pre.next; while (curr != null && curr.next != null ){ ListNode next = curr.next; curr.next = next.next; next.next = curr; pre.next = next; pre = curr; curr = pre.next; } return dummy.next; } }
两数相加 题目链接
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 class Solution { public ListNode addTwoNumbers (ListNode l1, ListNode l2) { ListNode res = new ListNode(-1 ); ListNode curr = res; int carry = 0 ; while (l1 != null || l2 != null ){ int n1 = l1 != null ? l1.val : 0 ; int n2 = l2 != null ? l2.val : 0 ; int num = n1 + n2 + carry; carry = num / 10 ; num = num % 10 ; curr.next = new ListNode(num); curr = curr.next; if (l1 != null ){ l1 = l1.next; } if (l2 != null ){ l2 = l2.next; } } if (carry == 1 ){ curr.next = new ListNode(1 ); } return res.next; } }
大数加法
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 import java.util.*;public class Solution { public String solve (String s, String t) { int i = s.length() - 1 ; int j = t.length() - 1 ; int carry = 0 ; StringBuilder sb = new StringBuilder(); while (i >= 0 || j >= 0 || carry != 0 ){ int x = i < 0 ? 0 : s.charAt(i--) - '0' ; int y = j < 0 ? 0 : t.charAt(j--) - '0' ; int sum = x + y + carry; sb.append(sum % 10 ); carry = sum / 10 ; } return sb.reverse().toString(); } }
二叉树 重建二叉树
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 import java.util.*;public class Solution { public TreeNode reConstructBinaryTree (int [] pre,int [] in) { Map<Integer,Integer> map = new HashMap(); for (int i = 0 ; i < in.length; i++){ map.put(in[i],i); } return dfs(0 ,pre.length - 1 ,0 ,in.length - 1 ,pre,in,map); } public TreeNode dfs (int pl,int pr,int il,int ir,int [] pre,int [] in,Map<Integer,Integer> map) { if (pl > pr){ return null ; } int k = map.get(pre[pl]); TreeNode root = new TreeNode(pre[pl]); root.left = dfs(pl + 1 ,pl + k -il,il,k-1 ,pre,in,map); root.right = dfs(pl + k- il + 1 ,pr,k+1 ,ir,pre,in,map); return root; } }
在二叉树中找到两个节点的最近公共祖先
以下图片来自于牛客¥ABCDEF
题解 代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 import java.util.*;public class Solution { public int lowestCommonAncestor (TreeNode root, int o1, int o2) { return dfs(root,o1,o2).val; } public TreeNode dfs (TreeNode root ,int o1,int o2) { if (root == null || root.val == o1 || root.val == o2){ return root; } TreeNode left = dfs(root.left,o1,o2); TreeNode right = dfs(root.right,o1,o2); if (left != null && right != null ){ return root; } return left == null ? right : left; } }
对称的二叉树 题目链接
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class Solution { public boolean isSymmetric (TreeNode root) { return root == null ? true : recur(root.left,root.right); } public boolean recur (TreeNode A,TreeNode B) { if (A == null && B == null ){ return true ; } if (A == null || B == null || A.val != B.val){ return false ; } return recur(A.left,B.right) && recur(A.right,B.left); } }
叶子相似的树 叶子相似的树
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 class Solution { List<Integer> res1 = new ArrayList(); List<Integer> res2 = new ArrayList(); public boolean leafSimilar (TreeNode root1, TreeNode root2) { dfs(root1,res1); dfs(root2,res2); return res1.equals(res2); } public void dfs (TreeNode root,List<Integer> res) { if (root.left == null && root.right == null ){ res.add(root.val); }else { if (root.left != null ){ dfs(root.left,res); } if (root.right != null ){ dfs(root.right,res); } } } }
二叉树的右视图 题目链接
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class Solution { public List<Integer> rightSideView (TreeNode root) { List<Integer> res = new ArrayList(); if (root == null ){ return res; } Queue<TreeNode> q = new LinkedList(); q.offer(root); while (!q.isEmpty()){ int size = q.size(); for (int i = 0 ; i < size; i++){ TreeNode node = q.poll(); if (node.left != null ){ q.offer(node.left); } if (node.right != null ){ q.offer(node.right); } if (i == size - 1 ){ res.add(node.val); } } } return res; } }
二叉树根节点到叶子节点和为指定值的路径 题目链接
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 import java.util.*;public class Solution { ArrayList<ArrayList<Integer>> res = new ArrayList(); ArrayList<Integer> tmp = new ArrayList(); public ArrayList<ArrayList<Integer>> pathSum (TreeNode root, int sum) { dfs(root,sum,0 ); return res; } public void dfs (TreeNode root, int sum,int cnt) { if (root == null ){ return ; } tmp.add(root.val); cnt += root.val; if (root.left == null && root.right == null ){ if (sum == cnt){ res.add(new ArrayList(tmp)); } }else { dfs(root.left,sum,cnt); dfs(root.right,sum,cnt); } tmp.remove(tmp.size() - 1 ); } }
二叉树根节点到叶子结点的所有路径和 题目链接
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 public class Solution { public int sumNumbers (TreeNode root) { if (root == null ){ return 0 ; } return dfs(root,0 ); } public int dfs (TreeNode root, int sum) { if (root == null ){ return 0 ; }else { sum = sum * 10 + root.val; if (root.left == null && root.right == null ){ return sum; }else { return dfs(root.left,sum) + dfs(root.right,sum); } } } }
二叉树从根节点到叶子结点路径问题 使用回溯求出所有路径,再根据具体题目要求筛选结果 代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 class Solution { List<List<Integer>> ret = new LinkedList<List<Integer>>(); Deque<Integer> path = new LinkedList<Integer>(); public List<List<Integer>> pathSum(TreeNode root) { dfs(root); return ret; } public void dfs (TreeNode root) { if (root == null ) { return ; } path.offerLast(root.val); if (root.left == null && root.right == null ) { ret.add(new LinkedList<Integer>(path)); } dfs(root.left); dfs(root.right); path.pollLast(); } }
二叉树中是否存在节点和为指定值的路径 题目链接
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public class Solution { public boolean hasPathSum (TreeNode root, int sum) { if (root == null ){ return false ; } sum -= root.val; if (sum == 0 && root.left == null && root.right == null ){ return true ; } return hasPathSum(root.left,sum) || hasPathSum(root.right,sum); } }
二叉树的最大路径和 题目链接
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 public class Solution { private int Max = Integer.MIN_VALUE; public int maxPathSum (TreeNode root) { dfs(root); return Max; } public int dfs (TreeNode root) { if (root == null ){ return 0 ; } int left = dfs(root.left); int right = dfs(root.right); int curr = root.val; if (left > 0 ){ curr += left; } if (right > 0 ){ curr += right; } Max = Math.max(Max,curr); return Math.max(root.val,Math.max(left,right) + root.val); } }
左叶子之和 题目链接
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 class Solution { public int sumOfLeftLeaves (TreeNode root) { if (root == null ){ return 0 ; } int sum = 0 ; Queue<TreeNode> q = new LinkedList(); q.offer(root); while (!q.isEmpty()){ int size = q.size(); for (int i = 0 ; i < size; i++){ TreeNode node = q.poll(); if (node.left != null ){ if (node.left.left == null && node.left.right == null ){ sum += node.left.val; }else { q.offer(node.left); } } if (node.right != null ){ q.offer(node.right); } } } return sum; } }
二叉树的所有路径 题目链接
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 class Solution { public List<String> binaryTreePaths (TreeNode root) { List<String> paths = new ArrayList(); if (root == null ){ return paths; } constructPath(root,"" ,paths); return paths; } public void constructPath (TreeNode root,String s,List<String> paths) { if (root != null ){ StringBuilder sb = new StringBuilder(s); sb.append(root.val); if (root.left == null && root.right == null ){ paths.add(sb.toString()); }else { sb.append("->" ); constructPath(root.left,sb.toString(),paths); constructPath(root.right,sb.toString(),paths); } } } }
动态规划 子数组的最大累加和问题
以下图片来自于牛客¥ABCDEF
题解
代码如下: 解法1:循环
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public static int helper (int [] array) { int len = array.length; if (len == 0 ) { return 0 ; } int currSum = array[0 ]; int maxSum = array[0 ]; for (int i = 1 ; i < len; i++) { if (currSum > 0 ) { currSum += array[i]; } else { currSum = array[i]; } maxSum = Math.max(maxSum, currSum); } return maxSum; }
解法2:DP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 import java.util.*;public class Solution { public int maxsumofSubarray (int [] arr) { int [] dp = new int [arr.length]; dp[0 ] = arr[0 ]; int res = arr[0 ]; for (int i = 1 ; i< arr.length; i++){ if (dp[i-1 ] > 0 ){ dp[i] = dp[i-1 ] + arr[i]; }else { dp[i] = arr[i]; } res = Math.max(res,dp[i]); } return res; } }
最长递增子序列 1. 题目链接
代码如下: 解法一:DP(超时)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 import java.util.*;public class Solution { public int [] LIS (int [] arr) { int [] dp = new int [arr.length]; int max = 1 ; Arrays.fill(dp, 1 ); for (int i = 1 ; i < arr.length; i ++) { for (int j = 0 ; j < i; j ++) { if (arr[i] > arr[j]) { dp[i] = Math.max(dp[i], dp[j] + 1 ); max = Math.max(max, dp[i]); } } } int [] res = new int [max]; int index = dp.length - 1 ; while (index >= 0 ) { if (dp[index] == max) { res[max - 1 ] = arr[index]; max --; } index --; } return res; } }
解法二:贪心+二分
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 import java.util.*;public class Solution { public int [] LIS (int [] arr) { int [] d = new int [arr.length]; int [] index = new int [arr.length]; int len = 0 ; d[len] = arr[len]; index[0 ] = 0 ; for (int i = 1 ; i < arr.length; i ++) { if (arr[i] > d[len]) { len ++; d[len] = arr[i]; index[i] = len; } else { int l = 0 , r = len; while (l <= r) { int mid = (l + r) / 2 ; if (d[mid] < arr[i]) { l = mid + 1 ; } else { r = mid - 1 ; } } d[l] = arr[i]; index[i] = l; } } int [] res = new int [len + 1 ]; int cur = arr.length - 1 ; while (cur >= 0 ) { if (index[cur] == len) { res[len] = arr[cur]; len --; } cur --; } return res; } }
2.题目链接
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 class Solution { public int lengthOfLIS (int [] nums) { int n = nums.length; int [] dp = new int [n]; Arrays.fill(dp,1 ); for (int i = 1 ; i < n; i++){ for (int j= 0 ; j < i; j++){ if (nums[j] < nums[i]){ dp[i] = Math.max(dp[i],dp[j] + 1 ); } } } int max = 0 ; for (int i = 0 ; i < n; i++){ max = Math.max(max,dp[i]); } return max; } }
最长公共子序列(返回值为子序列的长度) 题目链接
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class Solution { public int longestCommonSubsequence (String text1, String text2) { int m = text1.length(); int n = text2.length(); int [][] dp = new int [m+1 ][n+1 ]; for (int i = 1 ; i <= m; i++){ char ch1 = text1.charAt(i-1 ); for (int j = 1 ; j <= n; j++){ char ch2 = text2.charAt(j-1 ); if (ch1 == ch2){ dp[i][j] = dp[i-1 ][j-1 ] + 1 ; }else { dp[i][j] = Math.max(dp[i-1 ][j],dp[i][j-1 ]); } } } return dp[m][n]; } }
最长公共子序列(返回值为子序列) 题目链接
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 import java.util.*;public class Solution { public String LCS (String s1, String s2) { int len1 = s1.length(); int len2 = s2.length(); int [][] dp = new int [len1 + 1 ][len2 + 1 ]; for (int i = 1 ; i <= len1; i++){ for (int j = 1 ; j <= len2; j++){ if (s1.charAt(i-1 ) == s2.charAt(j-1 )){ dp[i][j] = dp[i-1 ][j-1 ] + 1 ; }else { dp[i][j] = Math.max(dp[i-1 ][j],dp[i][j-1 ]); } } } StringBuilder sb = new StringBuilder(); int a = len1; int b = len2; while (a != 0 && b != 0 ){ if (s1.charAt(a-1 ) == s2.charAt(b-1 )){ sb.append(s1.charAt(a-1 )); a--; b--; }else { if (dp[a-1 ][b] > dp[a][b-1 ]){ a--; }else { b--; } } } if (sb.length() == 0 ){ return "-1" ; }else { return sb.reverse().toString(); } } }
不相交的线 题目链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class Solution { public int maxUncrossedLines (int [] nums1, int [] nums2) { int m = nums1.length; int n = nums2.length; int [][] dp = new int [m+1 ][n+1 ]; for (int i = 1 ; i <= m; i++){ int num1 = nums1[i-1 ]; for (int j = 1 ; j <= n; j++){ int num2 = nums2[j-1 ]; if (num1 == num2){ dp[i][j] = dp[i-1 ][j-1 ] + 1 ; }else { dp[i][j] = Math.max(dp[i][j-1 ],dp[i-1 ][j]); } } } return dp[m][n]; } }
买卖股票的最佳时机 题目链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 import java.util.*;public class Solution { public int maxProfit (int [] prices) { int min = Integer.MAX_VALUE; int maxProfit = 0 ; for (int i = 0 ; i < prices.length; i++){ if (prices[i] < min){ min = prices[i]; }else if (prices[i] - min > maxProfit){ maxProfit = prices[i] - min; } } return maxProfit; } }
买卖股票的最佳时机 II 题目链接
代码如下:
编辑距离 题目链接
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 import java.util.*;public class Solution { public int minEditCost (String str1, String str2, int ic, int dc, int rc) { int m = str1.length(); int n = str2.length(); int [][] dp = new int [m+1 ][n+1 ]; for (int j = 1 ; j <= n; j++){ dp[0 ][j] = j * ic; } for (int i = 1 ; i <= m; i++){ dp[i][0 ] = i * dc; } for (int i = 1 ; i <= m; i++){ for (int j = 1 ; j <= n; j++){ if (str1.charAt(i-1 ) == str2.charAt(j-1 )){ dp[i][j] = dp[i-1 ][j-1 ]; }else { int insert = dp[i][j-1 ] + ic; int delete = dp[i-1 ][j] + dc; int replace = dp[i-1 ][j-1 ] + rc; dp[i][j] = Math.min(Math.min(insert,delete),replace); } } } return dp[m][n]; } }
零钱兑换 题目链接
奇怪的打印机 题目链接
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class Solution { public int strangePrinter (String s) { int n = s.length(); int [][] f = new int [n][n]; for (int i = n - 1 ; i >= 0 ; i--) { f[i][i] = 1 ; for (int j = i + 1 ; j < n; j++) { if (s.charAt(i) == s.charAt(j)) { f[i][j] = f[i][j - 1 ]; } else { int minn = Integer.MAX_VALUE; for (int k = i; k < j; k++) { minn = Math.min(minn, f[i][k] + f[k + 1 ][j]); } f[i][j] = minn; } } } return f[0 ][n - 1 ]; } }
最大正方形 题目链接
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class Solution { public int maximalSquare (char [][] matrix) { int max = 0 ; if (matrix == null || matrix.length == 0 || matrix[0 ].length == 0 ){ return max; } int m = matrix.length; int n = matrix[0 ].length; int [][] dp = new int [m][n]; for (int i = 0 ; i < m; i++){ for (int j = 0 ; j < n; j++){ if (matrix[i][j] == '1' ){ if (i == 0 || j == 0 ){ dp[i][j] = 1 ; }else { dp[i][j] = Math.min(Math.min(dp[i - 1 ][j], dp[i][j - 1 ]), dp[i - 1 ][j - 1 ]) + 1 ; } } max = Math.max(max,dp[i][j]); } } return max * max; } }
中心扩散法 最长回文子串
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 import java.util.*;public class Solution { public int getLongestPalindrome (String A, int n) { int len = A.length(); if (len < 2 ){ return A.length(); } int max = 0 ; for (int i = 0 ; i < len - 1 ; i++){ String s1 = helper(A,i,i); String s2 = helper(A,i,i+1 ); String s3 = s1.length() > s2.length()? s1: s2; if (max < s3.length()){ max = s3.length(); } } return max; } public String helper (String s, int left, int right) { int len = s.length(); int i = left; int j = right; while (i >= 0 && j < len){ if (s.charAt(i) == s.charAt(j)){ i--; j++; }else { break ; } } return s.substring(i+1 ,j); } }
单调栈 直方图的水量(接雨水) 题目链接
代码如下(双指针):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 class Solution { public int trap (int [] height) { int left = 0 ; int right = height.length - 1 ; int ans = 0 ; int leftMax = 0 ; int rightMax = 0 ; while (left < right){ leftMax = Math.max(leftMax,height[left]); rightMax = Math.max(rightMax,height[right]); if (height[left] < height[right]){ ans += leftMax - height[left]; left++; }else { ans += rightMax - height[right]; right--; } } return ans; } }
代码如下(单调栈):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class Solution { public int trap (int [] height) { int ans = 0 ; Deque<Integer> stack = new LinkedList(); for (int i = 0 ; i < height.length; i++){ while (!stack.isEmpty() && height[i] > height[stack.peek()] ){ int top = stack.pop(); if (stack.isEmpty()){ break ; } int left = stack.peek(); int width = i - left - 1 ; int currHeight = Math.min(height[i],height[left]) - height[top]; ans += currHeight * width; } stack.push(i); } return ans; } }
柱状图中最大的矩形 题目链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 public int largestRectangleArea (int [] heights) { int res = 0 ; Stack<Integer> stack = new Stack<>(); int [] newHeights = new int [heights.length + 2 ]; newHeights[0 ] = 0 ; newHeights[newHeights.length-1 ] = 0 ; for (int i = 1 ; i < heights.length + 1 ; i++) { newHeights[i] = heights[i - 1 ]; } for (int i = 0 ; i < newHeights.length; i++) { while (!stack.isEmpty() && newHeights[i] < newHeights[stack.peek()]) { int cur = stack.pop(); int curHeight = newHeights[cur]; int leftIndex = stack.peek(); int rightIndex = i; int curWidth = rightIndex - leftIndex - 1 ; res = Math.max(res, curWidth * curHeight); } stack.push(i); } return res; }
去除重复字母 题目链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 class Solution { public String removeDuplicateLetters (String s) { int len = s.length(); char [] ss = s.toCharArray(); boolean [] visited = new boolean [26 ]; int [] lastIndex = new int [26 ]; for (int i = 0 ; i < len; i++){ lastIndex[ss[i] - 'a' ] = i; } Deque<Character> stack = new ArrayDeque(); for (int i = 0 ; i < len; i++){ if (visited[ss[i] - 'a' ]){ continue ; } while (!stack.isEmpty() && stack.peekLast() > ss[i] && lastIndex[stack.peekLast() - 'a' ] > i){ char ch = stack.pollLast(); visited[ch - 'a' ] = false ; } stack.offerLast(ss[i]); visited[ss[i] - 'a' ] = true ; } StringBuilder sb = new StringBuilder(); for (char c : stack){ sb.append(c); } return sb.toString(); } }
拼接最大数 拼接最大数
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 class Solution { public int [] maxNumber(int [] nums1, int [] nums2, int k) { int len1 = nums1.length; int len2 = nums2.length; int [] preMax = new int [k]; for (int i = 0 ; i <= k; i++){ if (i > len1 || k - i > len2){ continue ; } int [] max1 = minStack(nums1,i); int [] max2 = minStack(nums2,k-i); int [] tmp = mergeArray(max1,max2); if (compare(tmp,0 ,preMax,0 ) > 0 ){ System.arraycopy(tmp, 0 , preMax, 0 , k); } } return preMax; } public static int [] minStack(int [] nums, int k) { int n = nums.length; int [] res = new int [k]; Deque<Integer> stack = new ArrayDeque(); int index = 0 ; while (index < n) { while (index < n && (stack.isEmpty() || stack.peekLast() >= nums[index])) { stack.offerLast(nums[index++]); } if (index == n) { break ; } while (!stack.isEmpty() && stack.peekLast() < nums[index] && stack.size() + n - index - 1 >= k) { stack.pollLast(); } stack.offerLast(nums[index++]); } for (int i = 0 ; i < k; i++) { res[i] = stack.pollFirst(); } return res; } public int [] mergeArray(int [] subsequence1, int [] subsequence2) { int x = subsequence1.length, y = subsequence2.length; if (x == 0 ) { return subsequence2; } if (y == 0 ) { return subsequence1; } int mergeLength = x + y; int [] merged = new int [mergeLength]; int index1 = 0 , index2 = 0 ; for (int i = 0 ; i < mergeLength; i++) { if (compare(subsequence1, index1, subsequence2, index2) > 0 ) { merged[i] = subsequence1[index1++]; } else { merged[i] = subsequence2[index2++]; } } return merged; } public int compare (int [] subsequence1, int index1, int [] subsequence2, int index2) { int x = subsequence1.length, y = subsequence2.length; while (index1 < x && index2 < y) { int difference = subsequence1[index1] - subsequence2[index2]; if (difference != 0 ) { return difference; } index1++; index2++; } return (x - index1) - (y - index2); } }
滑动窗口最大值(单调队列) 题目链接
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 class Solution { public int [] maxSlidingWindow(int [] nums, int k) { Deque<Integer> queue = new ArrayDeque(); int [] res = new int [nums.length - k + 1 ]; int index = 0 ; for (int i = 0 ; i < nums.length; i++){ while (!queue.isEmpty() && queue.peekLast() < nums[i]){ queue.pollLast(); } queue.addLast(nums[i]); if (i >= k - 1 ){ res[index++] = queue.peekFirst(); if (i >= k-1 && nums[i - k + 1 ] == queue.peekFirst()){ queue.removeFirst(); } } } return res; } }
栈 设计getMin功能的栈 题目链接
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 import java.util.*;public class Solution { public Deque<Integer> s = new LinkedList(); public Deque<Integer> min_s = new LinkedList(); public int [] getMinStack (int [][] op) { List<Integer> res = new ArrayList(); for (int i = 0 ; i < op.length; i++){ if (op[i][0 ] == 1 ){ Push(op[i][1 ]); }else if (op[i][0 ] == 2 ){ Pop(); }else { res.add(getMin()); } } int [] ans = new int [res.size()]; for (int i = 0 ; i < ans.length; i++){ ans[i] = res.get(i); } return ans; } public void Push (int x) { s.push(x); if (min_s.isEmpty() || min_s.peek() > x){ min_s.push(x); } } public void Pop () { if (!s.isEmpty()){ if (s.peek().equals(min_s.peek())){ min_s.pop(); } s.pop(); } } public int getMin () { return min_s.peek(); } }
用两个栈实现队列 题目链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 class CQueue { Deque<Integer> stack1; Deque<Integer> stack2; public CQueue () { stack1 = new LinkedList<Integer>(); stack2 = new LinkedList<Integer>(); } public void appendTail (int value) { stack1.push(value); } public int deleteHead () { if (stack2.isEmpty()) { while (!stack1.isEmpty()) { stack2.push(stack1.pop()); } } if (stack2.isEmpty()) { return -1 ; } else { int deleteItem = stack2.pop(); return deleteItem; } } }
队列 用队列实现栈 225. 用队列实现栈
代码如下:
只使用一个队列:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 class MyStack { Queue<Integer> queue; public MyStack () { queue = new LinkedList<Integer>(); } public void push (int x) { int n = queue.size(); queue.offer(x); for (int i = 0 ; i < n; i++) { queue.offer(queue.poll()); } } public int pop () { return queue.poll(); } public int top () { return queue.peek(); } public boolean empty () { return queue.isEmpty(); } }
使用两个队列:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 class MyStack { Queue<Integer> queue1; Queue<Integer> queue2; public MyStack () { queue1 = new LinkedList<Integer>(); queue2 = new LinkedList<Integer>(); } public void push (int x) { queue2.offer(x); while (!queue1.isEmpty()) { queue2.offer(queue1.poll()); } Queue<Integer> temp = queue1; queue1 = queue2; queue2 = temp; } public int pop () { return queue1.poll(); } public int top () { return queue1.peek(); } public boolean empty () { return queue1.isEmpty(); } }
回溯 字符串的排列 题目链接
代码入下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 import java.util.*;public class Solution { public ArrayList<String> Permutation (String str) { int len = str.length(); char [] strs = str.toCharArray(); Arrays.sort(strs); ArrayList<String> res = new ArrayList(); Deque<Character> path = new ArrayDeque(); boolean [] used = new boolean [len]; dfs(strs,len,0 ,used,res,path); return res; } public void dfs (char [] strs,int len,int depth,boolean [] used,ArrayList<String> res,Deque<Character> path) { if (len == depth){ StringBuilder sb = new StringBuilder(); for (char ch : path){ sb.append(ch); } res.add(new String(sb)); return ; } for (int i = 0 ; i < len; i++){ if (used[i]){ continue ; } if (i > 0 && strs[i] == strs[i-1 ] && !used[i-1 ]){ continue ; } path.addLast(strs[i]); used[i] = true ; dfs(strs,len,depth + 1 ,used,res,path); path.removeLast(); used[i] = false ; } } }
全排列 II 题目链接
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 class Solution { public List<List<Integer>> permuteUnique(int [] nums) { int len = nums.length; Arrays.sort(nums); List<List<Integer>> res = new ArrayList(); Deque<Integer> path = new ArrayDeque(); boolean [] used = new boolean [len]; dfs(nums,len,0 ,used,path,res); return res; } public void dfs (int [] nums,int len,int depth,boolean [] used,Deque<Integer> path,List<List<Integer>> res) { if (depth == len){ res.add(new ArrayList(path)); return ; } for (int i = 0 ; i < len; i++){ if (used[i]){ continue ; } if (i > 0 && nums[i] == nums[i - 1 ] && !used[i - 1 ]) { continue ; } path.addLast(nums[i]); used[i] = true ; dfs(nums,len,depth + 1 ,used,path,res); path.removeLast(); used[i] = false ; } } }
括号生成 题目链接
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 public class Solution { public ArrayList<String> generateParenthesis (int n) { ArrayList<String> res = new ArrayList(); backtrack("" ,0 ,0 ,n,res); return res; } public void backtrack (String s,int open,int close,int n, List<String> res) { if (s.length() == n << 1 ){ res.add(s); return ; } if (open < n){ backtrack(s + "(" ,open + 1 ,close,n,res); } if (close < open){ backtrack(s + ")" ,open,close + 1 , n ,res); } } }
DFS 剑指 Offer 12. 矩阵中的路径 题目链接
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class Solution { public boolean exist (char [][] board, String word) { char [] words = word.toCharArray(); for (int i = 0 ; i < board.length; i++){ for (int j = 0 ; j < board[i].length; j++){ if (dfs(board,words,i,j,0 )){ return true ; } } } return false ; } public boolean dfs (char [][] board,char [] words,int i, int j, int k) { if (i >= board.length || i < 0 || j >= board[0 ].length || j < 0 || board[i][j] != words[k]){ return false ; } if ( k == words.length - 1 ){ return true ; } board[i][j] = '\0' ; boolean res = dfs(board,words,i+1 ,j,k+1 ) || dfs(board,words,i-1 ,j,k+1 ) || dfs(board,words,i,j+1 ,k+1 ) ||dfs(board,words,i,j-1 ,k+1 ); board[i][j] = words[k]; return res; } }
合并区间 题目链接
代码入下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 import java.util.*;public class Solution { public ArrayList<Interval> merge (ArrayList<Interval> intervals) { ArrayList<Interval> res = new ArrayList(); Collections.sort(intervals,(a,b)->{ return a.start - b.start; }); int i = 0 ; int n = intervals.size(); while (i < n){ int left = intervals.get(i).start; int right = intervals.get(i).end; while (i < n - 1 && intervals.get(i+1 ).start <= right){ right = Math.max(right,intervals.get(i+1 ).end); i++; } res.add(new Interval(left,right)); i++; } return res; } }