publicintpivotIndex(int[] nums){ int sum = 0; for (int num : nums) sum += num; int left = 0; for (int i = 0; i < nums.length; i++) { if (i > 0) left += nums[i - 1]; int right = sum - nums[i] - left; if (left == right) { return i; } } return -1; }
publicdoublemyPow(double x, int n){ double result = 1.0; for (int i = n; i != 0; i /= 2) { if (i % 2 != 0) result *= x; x *= x; } return n < 0 ? 1 / result : result; }
publicintsearchInsert(int[] nums, int target){ int lo = 0, hi = nums.length - 1; while (lo <= hi) { int mid = (lo + hi) >>> 1; if (nums[mid] > target) hi = mid - 1; elseif (nums[mid] < target) lo = mid + 1; elsereturn mid; } return lo; }
744. 寻找比目标字母大的最小字母 Find Smallest Letter Greater Than Targetex744.java
1 2 3 4 5 6 7 8 9 10
publiccharnextGreatestLetter(char[] letters, char target){ int lo = 0, hi = letters.length - 1; if (target >= letters[hi]) return letters[0]; while (lo < hi) { int mid = (lo + hi) >>> 1; if (letters[mid] <= target) lo = mid + 1; else hi = mid; } return letters[lo]; }
852. 山脉数组的峰顶索引 Peak Index in a Mountain Arrayex852.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
publicintpeakIndexInMountainArray(int[] A){ int lo = 1, hi = A.length - 2; while (lo <= hi) { int mid = (lo + hi) >>> 1; if (A[mid] <= A[mid - 1]) hi = mid - 1; elseif (A[mid] <= A[mid + 1]) lo = mid + 1; elsereturn mid; } return -1; }
publicintpeakIndexInMountainArray2(int[] A){ for (int i = 1; i < A.length; i++) if (A[i - 1] > A[i]) return i - 1; return -1; }
//如果被除数大于或等于除数,则进行如下循环,定义变量t等于除数,定义计数p //当t的两倍小于等于被除数时,进行如下循环,t扩大一倍,p扩大一倍,然后更新res和m publicintdivide(int dividend, int divisor){ if (divisor == 0 || (dividend == Integer.MIN_VALUE && divisor == -1)) return Integer.MAX_VALUE; long m = Math.abs(dividend), n = Math.abs(divisor), res = 0; int sign = (dividend < 0) ^ (divisor < 0) ? -1 : 1; if (n == 1) return (int) (sign > 0 ? m : -m); while (m >= n) { long t = n, p = 1; while (m >= (t << 1)) { t <<= 1; p <<= 1; } res += p; m -= t; } return (int) (sign > 0 ? res : -res); }
public List<Integer> findClosestElements(int[] arr, int k, int x){ List<Integer> list = new ArrayList<>(k); int lo = 0, hi = arr.length - k - 1; while (lo <= hi) { int mid = (lo + hi) >>> 1; if (Math.abs(x - arr[mid]) > Math.abs(x - arr[mid + k])) lo = mid + 1; else hi = mid - 1; } for (int i = 0; i < k; i++) list.add(arr[lo + i]); return list; }
//非二分法,采用首尾逼近 public List<Integer> findClosestElements2(int[] arr, int k, int x){ List<Integer> list = new ArrayList<>(k); for (int i : arr) list.add(i); while (list.size() > k) { if (x - list.get(0) <= list.get(list.size() - 1) - x) list.remove(list.size() - 1); else list.remove(list.get(0)); } return list; }
034. 在排序数组中查找元素的第一个和最后一个位置 Find First and Last Position of Element in Sorted Array Arrayex034.java
publicint[] searchRange(int[] nums, int target) { int[] range = newint[]{-1, -1}; if (nums.length < 1) return range; int lo = 0, hi = nums.length - 1; while (lo < hi) { int mid = (lo + hi) >>> 1; if (nums[mid] < target) lo = mid + 1; else hi = mid; } if (nums[hi] != target) return range; range[0] = hi; hi = nums.length - 1; while (lo <= hi) { int mid = (lo + hi) >>> 1; if (nums[mid] > target) hi = mid - 1; else lo = mid + 1; } range[1] = lo - 1; return range; }
153. 寻找旋转排序数组中的最小值 Find Minimum in Rotated Sorted Arrayex153.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
publicintfindMin(int[] nums){ for (int i = 1; i < nums.length; i++) if (nums[i] < nums[i - 1]) return nums[i]; return nums[0]; }
publicintfindMin2(int[] nums){ int lo = 0, hi = nums.length - 1; if (nums[lo] <= nums[hi]) return nums[lo]; while (lo != hi - 1) { int mid = (lo + hi) >>> 1; if (nums[mid] > nums[lo]) lo = mid; else hi = mid; } return nums[lo] < nums[hi] ? nums[lo] : nums[hi]; }
publicintfindPeakElement(int[] nums){ int lo = 0, hi = nums.length - 1; while (lo < hi) { int mid = (lo + hi) >>> 1; if (nums[mid] < nums[mid + 1]) lo = mid + 1; else hi = mid; } return hi; }
publicintfindPeakElement2(int[] nums){ for (int i = 1; i < nums.length; i++) if (nums[i] < nums[i - 1]) return i - 1; return nums.length - 1; }
publicintfirstBadVersion(int n){ int lo = 1, hi = n; while (lo < hi) { int mid = (lo + hi) >>> 1; if (isBadVersion(mid)) hi = mid; else lo = mid + 1; } return lo; }
033. 搜索旋转排序数组 Search in Rotated Sorted Arrayex033.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
publicintsearch(int[] nums, int target){ int lo = 0, hi = nums.length - 1; while (lo <= hi) { int mid = (lo + hi) >>> 1; if (nums[mid] == target) return mid; elseif (nums[mid] > nums[lo]) { //左边有序 lo...mid if (nums[mid] > target && target >= nums[lo]) hi = mid - 1; else lo = mid + 1; } elseif (nums[mid] < nums[hi]) { //右边有序 mid...hi if (nums[mid] < target && target <= nums[hi]) lo = mid + 1; else hi = mid - 1; } } return -1; }
publicintguessNumber(int n){ int lo = 0, hi = n; while (lo <= hi) { int mid = (lo + hi) >>> 1; int result = guess(mid); if (result == 0) return mid; elseif (result < 0) hi = mid - 1; else lo = mid + 1; } return -1; }
publicintmySqrt(int x){ if (x <= 1) return x; //right = x int left = 0, right = x / 2 + 1; while (left < right) { int mid = (left + right) >>> 1; if (x / mid >= mid) left = mid + 1; else right = mid; } return right - 1; }
//牛顿逼近法 publicintmySqrt2(int x){ if (x == 0) return0; double last = 0; double res = 1; while (last != res) { last = res; res = (res + x / res) / 2; } return (int) res; }
430. 扁平化多级双向链表 Flatten a Multilevel Doubly Linked Listex430.java
public ListNode rotateRight(ListNode head, int k){ if (head == null || head.next == null) return head; ListNode curr = head; int sum = 1; while (curr.next != null) { sum++; curr = curr.next; } curr.next = head; sum = sum - k % sum; for (int i = 0; i < sum; i++) curr = curr.next; head = curr.next; curr.next = null; return head; }
classListNode{ int val; ListNode next;
ListNode(int x) { val = x; } }
138. 复制带随机指针的链表 Copy List with Random Pointerex138.java
public ListNode removeNthFromEnd(ListNode head, int n){ ListNode slow = head; ListNode fast = head; for (int i = 0; i < n; i++) fast = fast.next; if (fast == null) return head.next;//删除第一个结点 while (fast.next != null) { fast = fast.next; slow = slow.next; } slow.next = slow.next.next; return head; }
public ListNode removeNthFromEnd2(ListNode head, int n){ ListNode dummyHead = new ListNode(-1); dummyHead.next = head; ListNode slow = dummyHead; ListNode fast = head; for (int i = 0; i < n; i++) fast = fast.next; while (fast != null) { fast = fast.next; slow = slow.next; } slow.next = slow.next.next; return dummyHead.next; }
public ListNode reverseBetween(ListNode head, int m, int n){ ListNode dummyHead = new ListNode(0); dummyHead.next = head; ListNode first = dummyHead; for (int i = 0; i < m - 1; i++) { first = first.next; } ListNode curr = first.next; for (int i = 0; i < n - m; i++) { ListNode node = curr.next; curr.next = node.next; node.next = first.next; first.next = node; } return dummyHead.next; }
//解决的不好,不易理解,纯靠画图完成 public ListNode reverseBetween2(ListNode head, int m, int n){ if (head == null || head.next == null) return head; ListNode pre = null, s = head, t = head, curr = head; //构造结构 // 1 -> 2 -> 3 -> 4 -> 5 -> null, m=2, n=4 //pre preS s t for (int i = 1; (i <= n) && curr != null; i++) { if (i < m) pre = curr; curr = curr.next; t = curr; } ListNode preS; if (pre != null) preS = pre.next; else preS = head; s = preS.next; //把从s到t的前一个逆序 // 1 -> 2 <-> 3 <- 4 5 -> null, m=2, n=4 //pre preNext preS st ListNode preNext = preS; while (s != t && s != null) { ListNode temp = s.next; s.next = preS; preS = s; s = temp; } //最后整理链表顺序 preNext.next = t; if (pre != null) pre.next = preS; else head = preS; return head; }
//不反转链表通过Stack存储数据并弹出,然后模仿Stack在头部添加新结点 public ListNode addTwoNumbers(ListNode l1, ListNode l2){ Stack<Integer> stack1 = new Stack<>(); Stack<Integer> stack2 = new Stack<>(); ListNode p = l1, q = l2; while (p != null) { stack1.push(p.val); p = p.next; } while (q != null) { stack2.push(q.val); q = q.next; } int carry = 0; ListNode first = null; while (!stack1.isEmpty() || !stack2.isEmpty()) { int x = stack1.isEmpty() ? 0 : stack1.pop(); int y = stack2.isEmpty() ? 0 : stack2.pop(); int sum = x + y + carry; carry = sum / 10; ListNode temp = first; first = new ListNode(sum % 10); first.next = temp; } if (carry > 0) { ListNode temp = first; first = new ListNode(carry); first.next = temp; } return first; }
int carry = 0; ListNode dummyHead = new ListNode(0); ListNode curr = dummyHead; ListNode p = rl1, q = rl2; while (p != null || q != null) { int x = p != null ? p.val : 0; int y = q != null ? q.val : 0; int sum = x + y + carry; carry = sum / 10; curr.next = new ListNode(sum % 10); curr = curr.next; if (p != null) p = p.next; if (q != null) q = q.next; } if (carry > 0) curr.next = new ListNode(carry); return reverse(dummyHead.next); }
private ListNode reverse(ListNode head){ ListNode pre = null; while (head != null) { ListNode temp = head.next; head.next = pre; pre = head; head = temp; } return pre; }
public ListNode[] splitListToParts(ListNode root, int k) { //总数 int sum = 0; ListNode curr = root; while (curr != null) { sum++; curr = curr.next; } curr = root; //每个部分的基础大小 int per = sum < k ? 1 : sum / k; //额外分配多1的结点数(extra<per) int extra = sum < k ? 0 : sum % k;
ListNode[] result = new ListNode[k]; ListNode pre = null; for (int i = 0; i < k; i++, --extra) { result[i] = curr; for (int j = 0; (j < per + (extra > 0 ? 1 : 0)) && curr != null; j++) { pre = curr; curr = curr.next; } if (pre != null) pre.next = null; } return result; }
publicintnumComponents(ListNode head, int[] G){ Set<Integer> g = new HashSet<>(); int num = 0; for (int i : G) g.add(i); while (head != null) { if (g.contains(head.val)) { if (head.next == null || !g.contains(head.next.val)) num++; } head = head.next; } return num; }
publicintnumComponents2(ListNode head, int[] G){ Set<Integer> g = new HashSet<>(); for (int i : G) g.add(i); int nums = 0; while (head != null) { if (g.contains(head.val)) { ++nums; ListNode next = head.next; while (next != null && g.contains(next.val)) { next = next.next; } head = next; continue; } head = head.next; } return nums; }
publicintsearch(int[] nums, int target){ int lo = 0; int hi = nums.length - 1; if (lo == hi) { if (target == nums[lo]) return lo; elsereturn -1; } int mid; while (nums[lo] < nums[hi]) { mid = (lo + hi) / 2; if (lo == mid || hi == mid) { if (target == nums[lo]) return lo; elseif (target == nums[hi]) return hi; elsereturn -1; } if (target < nums[mid]) hi = mid; elseif (target > nums[mid]) lo = mid; elsereturn mid; } return -1; }
083. 删除排序链表中的重复元素 Remove Duplicates from Sorted Listex083.java