3. 无重复字符的最长子串
第一次代码空间复杂度大:
public class Solution { public int lengthOfLongestSubstring(String s) { if(s.length() <= 0) return 0; StringBuffer strb = new StringBuffer(s.length()); strb.append(s, 0, 1); int result = 1; int length = 1; for (int i = 1; i < s.length(); i++) { if(strb.indexOf(s.substring(i,i+1)) != -1){ int index = strb.indexOf(s.substring(i,i+1)); if(result < length) result = length; strb = new StringBuffer(strb.substring(index + 1, strb.length())); } strb.append(s,i,i+1); length = strb.length(); } return result > length ? result : length; } }
第二次 滑动窗口+map
public class Solution { public int lengthOfLongestSubstring(String s) { Map<Character, Integer> map = new HashMap<>(); int n = s.length(), result = 0; int start = 0, end = 0; for (; end < n; end++) { char op = s.charAt(end); if(map.containsKey(op)){ start = Math.max(start, map.get(op)); } result = Math.max(result, end - start + 1); map.put(op, end + 1); } return result; } }
4. 寻找两个正序数组的中位数
第一次,时间复杂度(m+n),空间复杂度(m+n)不符合
class Solution { public double findMedianSortedArrays(int[] nums1, int[] nums2) { int n = nums1.length + nums2.length; int[]num = new int[n+1]; int i = 0, j = 0, k = 0; for (; i < n && j < nums1.length && k < nums2.length; i++) { if(nums1[j] < nums2[k]){ num[i] = nums1[j++]; }else{ num[i] = nums2[k++]; } } while(j < nums1.length){ num[i++] = nums1[j++]; } while(k < nums2.length){ num[i++] = nums2[k++]; } if(n % 2 == 0){ return (double) (num[n/2 - 1] + num[n/2]) / 2; }else{ return (double) num[n/2]; } } }
第二次:二分查找(太强了,我太菜了)
public double findMedianSortedArrays(int[] nums1, int[] nums2) { int n = nums1.length; int m = nums2.length; int left = (n + m + 1) / 2; int right = (n + m + 2) / 2; //将偶数和奇数的情况合并,如果是奇数,会求两次同样的 k 。 return (getKth(nums1, 0, n - 1, nums2, 0, m - 1, left) + getKth(nums1, 0, n - 1, nums2, 0, m - 1, right)) * 0.5; } private int getKth(int[] nums1, int start1, int end1, int[] nums2, int start2, int end2, int k) { int len1 = end1 - start1 + 1; int len2 = end2 - start2 + 1; //让 len1 的长度小于 len2,这样就能保证如果有数组空了,一定是 len1( 牛逼啊 ) if (len1 > len2) return getKth(nums2, start2, end2, nums1, start1, end1, k); if (len1 == 0) return nums2[start2 + k - 1]; if (k == 1) return Math.min(nums1[start1], nums2[start2]); int i = start1 + Math.min(len1, k / 2) - 1; int j = start2 + Math.min(len2, k / 2) - 1; if (nums1[i] > nums2[j]) { return getKth(nums1, start1, end1, nums2, j + 1, end2, k - (j - start2 + 1)); } else { return getKth(nums1, i + 1, end1, nums2, start2, end2, k - (i - start1 + 1)); } }