目录
3. 无重复字符的最长子串(快慢指针、哈希表)
线性:
class Solution {
public int lengthOfLongestSubstring(String s) {
int max = 0 ;
Set<Character> set = new HashSet<Character>() ;
for(int i = 0, j = 0; j < s.length(); j ++){
while(set.contains(s.charAt(j))){
set.remove(s.charAt(i)) ;
i ++ ;
}
set.add(s.charAt(j));
max = Math.max(max,set.size()) ;
}
return max ;
}
}
改进:
class Solution {
public int lengthOfLongestSubstring(String s) {
int max = 0 ;
Map<Character,Integer> map = new HashMap<Character,Integer>() ;
for(int i = 0, j = 0; j < s.length(); j ++){
if(map.containsKey(s.charAt(j))){
i = Math.max(map.get(s.charAt(j)) + 1,i) ;
}
map.put(s.charAt(j),j) ;
max = Math.max(max,j-i+1) ;
}
return max ;
}
}
每次当新的重复元素加入到集合里面,统计集合长度。
4. 寻找两个正序数组的中位数
class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int m = nums1.length ;
int n = nums2.length ;
int k = (m+n)/2 ;
if( (m + n)%2 == 1){
return findKth(nums1,0,m-1,nums2,0,n-1,k+1) ;
} else {
return (findKth(nums1,0,m-1,nums2,0,n-1,k) +
findKth(nums1,0,m-1,nums2,0,n-1,k+1) ) /2.0;
}
}
public double findKth(int[] nums1, int l1, int h1, int[] nums2, int l2, int h2, int k){
int m = h1 - l1 + 1;
int n = h2 - l2 + 1;
if(m > n){ // 交换加快速度
return findKth(nums2,l2,h2,nums1,l1,h1,k) ;
}
if(m==0){
return nums2[l2+k-1] ; // 返回第k小的数
}
if(k == 1){
return Math.min(nums1[l1],nums2[l2]) ;
}
// 拆分
int na = Math.min(k/2,m) ;
int nb = k - na ;
int va = nums1[l1 + na - 1] ;
int vb = nums2[l2 + nb - 1] ;
// 在存在区间中找
if(va == vb){
return va ;
} else if( va > vb){ // 大前
return findKth(nums1, l1, l1 + na -1, nums2, l2 + nb, h2, k - nb) ;
} else{
return findKth(nums1, l1 + na , h1, nums2, l2, l2 + nb -1, k - na) ;
}
}
}
大前
215. 数组中的第K个最大元素
class Solution {
public int findKthLargest(int[] nums, int k) {
return quickSelect(nums, 0, nums.length - 1, nums.length-k) ;
}
public int quickSelect(int [] nums, int low, int high, int k){
int i, j ;
for( i = low, j = low; j < high ; j ++) {
if( nums[j] <= nums[high] ){
int temp = nums[i] ;
nums[i] = nums[j] ;
nums[j] = temp ;
i ++ ;
}
}
int temp = nums[i] ;
nums[i] = nums[j] ;
nums[j] = temp ;
if(i == k){
return nums[k] ;
} else if (i > k){
return quickSelect(nums, low, i -1, k) ;
} else {
return quickSelect(nums, i + 1, high, k) ;
}
}
}
23. 合并K个排序链表
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
if(lists.length == 0 ){
return null;
}
ListNode fakeHead = new ListNode(0);
ListNode p = fakeHead ;
PriorityQueue<ListNode> priorityQueue = new PriorityQueue<ListNode>(lists.length, (a,b)->a.val - b.val) ;
for(int i = 0; i < lists.length; i ++){
if(lists[i] != null){
priorityQueue.add(lists[i]) ;
}
}
while( !priorityQueue.isEmpty()){
ListNode temp = priorityQueue.poll() ;
p.next = temp ;
p = p.next ;
if(p.next != null){
priorityQueue.add(p.next) ;
}
}
return fakeHead.next ;
}
}
56. 合并区间
class Solution {
public int[][] merge(int[][] intervals) {
if(intervals.length == 0){
return intervals ;
}
Arrays.sort(intervals, (i1,i2)->Integer.compare(i1[0],i2[0])) ;
int[] previous = intervals[0] ;
List<int[]> result = new ArrayList<int[]>() ;
for( int i = 0; i < intervals.length; i ++){
int [] curr = intervals[i] ;
if(curr == null || previous[1] < curr[0]){
result.add(previous) ;
previous = curr ;
} else {
previous[1] = Math.max(previous[1],curr[1]) ;
}
if(i == intervals.length - 1){ // 最后一个要加上,previous
result.add(previous) ;
}
}
return result.toArray(new int[result.size()][]) ;
}
}
435. 无重叠区间
class Solution {
public int eraseOverlapIntervals(int[][] intervals) {
if(intervals.length == 0){
return 0;
}
Arrays.sort(intervals, (i1,i2) -> Integer.compare(i1[0],i2[0]));
int end = intervals[0][1], count = 0;
for(int i = 1; i < intervals.length; i ++){
if( intervals[i][0] < end){ // 重叠
end = Math.min(end, intervals[i][1]);
count ++ ;
} else {
end = intervals[i][1] ;
}
}
return count ;
}
}
class Solution {
public int eraseOverlapIntervals(int[][] intervals) {
Arrays.sort(intervals, (i1,i2) -> Integer.compare(i1[0],i2[0]));
return eraseOverlapIntervalsSolution(intervals,-1,0) ;
}
public int eraseOverlapIntervalsSolution(int[][] intervals, int prev, int curr) {
if(curr == intervals.length){
return 0 ;
}
int taken = Integer.MAX_VALUE; // 为什么要定义在里面
int notaken;
if( prev == -1 ||intervals[prev][1] <= intervals[curr][0] ){ //保留
taken = eraseOverlapIntervalsSolution(intervals,curr,curr+1);
}
notaken = eraseOverlapIntervalsSolution(intervals,prev,curr+1) + 1;
return Math.min(taken,notaken );
}
}