摘要:刷题recording
数组
二分查找
704、二分查找(easy)
最基本的二分查找思想,左闭右闭,<=
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| class Solution { public int search(int[] nums, int target) { int left = 0; int right = nums.length-1; while(left <=right){ int mid = (left + right)/2; if(nums[mid]>target){ right = mid-1; } else if(nums[mid] < target){ left = mid + 1; } else{ return mid; } } return -1; } }
|
35、搜索插入位置(easy)
相同代码下java的内存消耗竟然是cpp的4倍…
主要思想还是二分查找,找不到则把目标值按顺序插入,即返回L/R+1。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| class Solution { public int searchInsert(int[] nums, int target) { int left = 0; int right = nums.length-1;
while(left <= right){ int mid = (left + right)/2; if(nums[mid]>target){ right = mid-1; } else if(nums[mid]< target){ left = mid + 1; } else{ return mid; } } return left; } }
|
34、在排序数组中查找元素的第一个和最后一个位置(medium)
集合也可以(保存两个下标到集合中,然后打印输出)(为啥我想的把数组变为集合,然后取第一次和最后一次出现的位置,打印输出是错误的?答:好像是集合类调不了)
二分查找
第二次做还做吐了…qaq
找左边界:二分查找思想,相等的时候保存,继续往左查找,即right=mid-1;
找右边界:二分查找思想,相等的时候保存,继续往右查找,即left=mid+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
| class Solution { public int[] searchRange(int[] nums, int target) { int[] arr = new int[]{-1,-1}; int left =0,right = nums.length-1; while(left <= right){ int mid = (left + right)/2; if(nums[mid]>target){ right = mid -1; }else if(nums[mid] < target){ left = mid +1; }else{ arr[0] = mid; right = mid -1; } } left =0;right = nums.length-1; while(left <= right){ int mid = (left + right)/2; if(nums[mid]>target){ right = mid -1; }else if(nums[mid] < target){ left = mid +1; }else{ arr[1] = mid; left = mid +1; } } return arr; } }
|
69、x的平方根(easy)
中心思想:二分查找,考虑int*int变量长度,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| class Solution { public int mySqrt(int x) { int left = 0;int index =0; int right = x; while(left <= right){ int mid = left + (right-left)/2; if((long)mid*mid<=x){ index = mid; left = mid+1; }else{ right = mid-1; } } return index; } }
|
这个方法更加熟悉,与上面的解法相似,正常进行二分法,然后对返回结果进行考虑。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class Solution { public int mySqrt(int x) { int left = 0;int index =0; int right = x; while(left <= right){ int mid = left + (right-left)/2; if((long)mid*mid<x){ left = mid+1; }else if((long)mid*mid>x){ right = mid-1; }else{ return mid; } } return right; } }
|
367、有效的完全平方数(easy)
easy
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| class Solution { public boolean isPerfectSquare(int num) { int left =1,right = num; while(left<=right){ int mid = left +(right -left)/2; if((long)mid*mid<num){ left = mid+1; }else if((long)mid*mid>num){ right = mid-1; }else{ return true; } } return false; } }
|
双指针法
27、移除元素(easy)
1、暴力破解法
2、双指针法:快指针遍历数组,慢指针保存合适的值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| class Solution { public int removeElement(int[] nums, int val) { int fast=0; int slow=0; while(fast<nums.length){ if(nums[fast]!=val){ nums[slow] = nums[fast]; slow++; } fast++; } return slow; } }
|
26、删除有序数组中的重复项(easy)
双指针法:数组的一个值肯定会在数组里,于是从第二个数开始比较,快慢指针有点颠倒的意思,慢指针依旧用来保存数组,但是是从1开始,而快指针用来比较当前的值与之前一个值是否相等。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| class Solution { public int removeDuplicates(int[] nums) { if(nums.length ==0){ return 0; } int fast = 0; int slow =1; for(int i=1;i<nums.length;i++){ if(nums[i]!=nums[fast]){ nums[slow] = nums[i]; slow++; }fast++; } return slow; } }
|
!283、移动零(easy)
1、补0
2、双指针法:左右指针,有点搞脑子,以后再做做
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| class Solution { public void moveZeroes(int[] nums) { int n = nums.length, left = 0, right = 0; while (right < n) { if (nums[right] != 0) { swap(nums, left, right); left++; } right++; } }
public void swap(int[] nums, int left, int right) { int temp = nums[left]; nums[left] = nums[right]; nums[right] = temp; } }
|
!844、比较含退格的字符串(easy)
1、重构字符串
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| class Solution { public boolean backspaceCompare(String S, String T) { return build(S).equals(build(T)); }
public String build(String str) { StringBuffer ret = new StringBuffer(); int length = str.length(); for (int i = 0; i < length; ++i) { char ch = str.charAt(i); if (ch != '#') { ret.append(ch); } else { if (ret.length() > 0) { ret.deleteCharAt(ret.length() - 1); } } } return ret.toString(); } }
|
2、双指针法
两个字符串各一个指针,从后往前,一次遍历过程:指到“#”则指针加一,否则在>0的基础上减一,若<0则break,最终会各自得到一个值,然后比较两个值是否相等。
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 boolean backspaceCompare(String S, String T) { int i = S.length() - 1, j = T.length() - 1; int skipS = 0, skipT = 0;
while (i >= 0 || j >= 0) { while (i >= 0) { if (S.charAt(i) == '#') { skipS++; i--; } else if (skipS > 0) { skipS--; i--; } else { break; } } while (j >= 0) { if (T.charAt(j) == '#') { skipT++; j--; } else if (skipT > 0) { skipT--; j--; } else { break; } } if (i >= 0 && j >= 0) { if (S.charAt(i) != T.charAt(j)) { return false; } } else { if (i >= 0 || j >= 0) { return false; } } i--; j--; } return true; } }
|
977、有序数组的平方(easy)
双指针法:左右指针,分别比较
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| class Solution { public int[] sortedSquares(int[] nums) { int left =0,right = nums.length-1; int[] nums2 = new int[nums.length]; int index =nums.length-1; while(left<=right){ if(nums[left]*nums[left] <= nums[right]*nums[right]){ nums2[index--] = nums[right]*nums[right]; right--; }else{ nums2[index--] = nums[left]*nums[left]; left++; } } return nums2; } }
|
滑动窗口
!209、长度最小的子数组(m)
1、暴力破解法
2、滑动窗口:while(右指针小于右边界),当sum>=目标值的时候在while里一直减左指针下标
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 minSubArrayLen(int s, int[] nums) { int n = nums.length; if (n == 0) { return 0; } int ans = Integer.MAX_VALUE; int start = 0, end = 0; int sum = 0; while (end < n) { sum += nums[end]; while (sum >= s) { ans = Math.min(ans, end - start + 1); sum -= nums[start]; start++; } end++; } return ans == Integer.MAX_VALUE ? 0 : ans; } }
|
!!!904、水果成篮(m)
!!!76、最小覆盖字串(hard)
螺旋矩阵
59、螺旋矩阵(m)
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[][] generateMatrix(int n) { int top = 0,bottom = n-1,left = 0,right = n-1; int[][] target = new int[n][n]; int temp =1; while(temp <=(n*n)){ for(int i=left;i<=right;i++){ target[top][i] = temp; temp++; }top++; for(int i=top;i<=bottom;i++){ System.out.println(i); target[i][right] =temp; temp++; }right--; for(int i=right;i>=left;i--){ target[bottom][i] = temp; temp++; }bottom--; for(int i=bottom;i>=top;i--){ target[i][left] = temp; temp++; }left++; } return target; } }
|
!54、螺旋矩阵(m)
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
| class Solution { public List<Integer> spiralOrder(int[][] matrix) { List<Integer> order = new ArrayList<Integer>(); if (matrix == null || matrix.length == 0 || matrix[0].length == 0) { return order; } int rows = matrix.length, columns = matrix[0].length; int left = 0, right = columns - 1, top = 0, bottom = rows - 1; while (left <= right && top <= bottom) { for (int column = left; column <= right; column++) { order.add(matrix[top][column]); } for (int row = top + 1; row <= bottom; row++) { order.add(matrix[row][right]); } if (left < right && top < bottom) { for (int column = right - 1; column > left; column--) { order.add(matrix[bottom][column]); } for (int row = bottom; row > top; row--) { order.add(matrix[row][left]); } } left++; right--; top++; bottom--; } return order; } }
|
链表
迭代
203、移除链表元素(easy)
添加虚拟头节点:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| class Solution { public ListNode removeElements(ListNode head, int val) { if(head==null){ return null; } ListNode newhead = new ListNode(0); newhead.next = head; ListNode pre = newhead; ListNode cur = head; while(cur!=null){ if(cur.val == val){ pre.next = cur.next; cur = cur.next;
}else{ pre = pre.next; cur = cur.next; } } return newhead.next; } }
|
!206、反转链表(easy)
前一个节点,后一个节点
1 2 3 4 5 6 7 8 9 10 11 12 13
| class Solution { public ListNode reverseList(ListNode head) { ListNode pre = null; ListNode cur = head; while(cur!=null){ ListNode temp = cur.next; cur.next = pre; pre = cur; cur = temp; } return pre; } }
|
!24、两两交换链表中的节点(m)
与上题类似,一般都会设置一个虚拟头节点,然后将对下的一个或两个节点进行操作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class Solution { public ListNode swapPairs(ListNode head) { ListNode dummyHead = new ListNode(0); dummyHead.next = head; ListNode temp = dummyHead; while (temp.next != null && temp.next.next != null) { ListNode node1 = temp.next; ListNode node2 = temp.next.next; temp.next = node2; node1.next = node2.next; node2.next = node1; temp = node1; } return dummyHead.next; } }
|
19、删除链表的倒数第N个结点(m)
①利用长度
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| class Solution { public ListNode removeNthFromEnd(ListNode head, int n) { ListNode newhead = new ListNode(0); newhead.next = head; ListNode pp =newhead; ListNode temp = head; int length = 0; while(temp!=null){ length++; temp = temp.next; } int move = length - n; while(move>0){ move--; pp = pp.next; } pp.next = pp.next.next; return newhead.next; } }
|
②双指针:右指针先移动n位(n,即倒数第n个),然后左右一起移动,直到右指针为空。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class Solution { public ListNode removeNthFromEnd(ListNode head, int n) { ListNode dummy = new ListNode(0, head); ListNode first = head; ListNode second = dummy; for (int i = 0; i < n; ++i) { first = first.next; } while (first != null) { first = first.next; second = second.next; } second.next = second.next.next; ListNode ans = dummy.next; return ans; } }
|
02.07链表相交(easy)
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
| public class Solution { public ListNode getIntersectionNode(ListNode headA, ListNode headB) { ListNode curA = headA; ListNode curB = headB; int lenA = 0, lenB = 0; while (curA != null) { lenA++; curA = curA.next; } while (curB != null) { lenB++; curB = curB.next; } curA = headA; curB = headB; if (lenB > lenA) { int tmpLen = lenA; lenA = lenB; lenB = tmpLen; ListNode tmpNode = curA; curA = curB; curB = tmpNode; } int gap = lenA - lenB; while (gap-- > 0) { curA = curA.next; } while (curA != null) { if (curA == curB) { return curA; } curA = curA.next; curB = curB.next; } return null; } }
|
142、环形链表II(m)
①哈希表:用一个集合存所有的结点,然后比较是否已经包含contains。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| public class Solution { public ListNode detectCycle(ListNode head) { ListNode newhead = new ListNode(0); newhead.next = head; if(head == null || head.next == null){ return null; } ArrayList list = new ArrayList(); ListNode temp = newhead; while(temp!= null){ if(list.contains(temp)){ return temp; }else{ list.add(temp); } temp = temp.next; } return null; } }
|
②快慢指针
递归