LetCode高频题

目录

3. 无重复字符的最长子串(快慢指针、哈希表)

4. 寻找两个正序数组的中位数

215. 数组中的第K个最大元素

23. 合并K个排序链表


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 );
    }
}

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值