面试经典150题(101-104)

leetcode 150道题 计划花两个月时候刷完之未完成后转,今天(第1天)完成了4道(101-104)150:

101.(215. 数组中的第K个最大元素) 题目描述:

给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。
请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。

第一版(这个题看了好几天。。复习了快排的写法,也算有收获,最后还是看了解题)

class Solution {
    Random random=new Random();
    public int findKthLargest(int[] nums, int k) {
        return quickSort(nums,0,nums.length-1,nums.length-k);
    }
    public int quickSort(int[] nums, int left,int right,int k){
        if(left>=right){
            return nums[k];
        }
        int randomIndex=left+random.nextInt(right-left+1);
        swap(nums,left,randomIndex);
        int middleNum=nums[left];
        int leftTemp=left+1;
        int rightTemp=right;
        while(leftTemp<=rightTemp){
            while(leftTemp<=rightTemp&&nums[rightTemp]>middleNum){
                rightTemp--;
            }
            while(leftTemp<=rightTemp&&nums[leftTemp]<middleNum){
                leftTemp++;
            }
            if(leftTemp>=rightTemp){
                break;
            }
            swap(nums,leftTemp,rightTemp);
            leftTemp++;
            rightTemp--;
        }
        swap(nums,left,rightTemp);
        if(k==rightTemp){
            return nums[rightTemp];
        }else if(k>rightTemp){
            return quickSort(nums,rightTemp+1,right,k);
        }else{
           return quickSort(nums,left,rightTemp-1,k);
        }
    }
    public void swap(int[] nums, int left,int right){
        int temp=nums[left];
        nums[left]=nums[right];
        nums[right]=temp;
    }
}

第二版(用了java 自带的堆集合,大堆根)

class Solution {
    public int findKthLargest(int[] nums, int k) {
        int len=nums.length;
        PriorityQueue<Integer> priorityQueue=new PriorityQueue<Integer>(len,
        (o1,o2)->o2.compareTo(o1));
        for(int num:nums){
            priorityQueue.offer(num);
        }
        for(int i=0;i<k-1;i++){
            priorityQueue.poll();
        }
        return priorityQueue.peek();
    }
}

102.(373. 查找和最小的 K 对数字)题目描述:

给定两个以 非递减顺序排列 的整数数组 nums1 和 nums2 , 以及一个整数 k 。
定义一对值 (u,v),其中第一个元素来自 nums1,第二个元素来自 nums2 。
请找到和最小的 k 个数对 (u1,v1),  (u2,v2)  ...  (uk,vk)

第一版(我一上来就是全部结果拿到然后排序返回前K个,然后报超时,解题的去重不是很好的理解的。意思就是先将开头的放进去,然后下面取下一个要出现的组合时候只需要向右找就行这样就不会重复了)

class Solution {
    public List<List<Integer>> kSmallestPairs(int[] nums1, int[] nums2, int k) {
        List<List<Integer>> res=new ArrayList();
        PriorityQueue<int[]> priority=new PriorityQueue<int[]>(k,(o1,o2)->{
            return nums1[o1[0]]+nums2[o1[1]]-nums1[o2[0]]-nums2[o2[1]];
        });
        int m=nums1.length;
        int n=nums2.length;
        for(int i=0;i<Math.min(m,k);i++){
            priority.offer(new int[]{i,0});
        }
        while(k-->0&&!priority.isEmpty()){
            int[] temp=priority.poll();
            List<Integer> list=new ArrayList();
            list.add(nums1[temp[0]]);
            list.add(nums2[temp[1]]);
            res.add(list);
            if(temp[1]+1<n){
                priority.offer(new int[]{temp[0],temp[1]+1});
            }
        }
        return res;

    }
}

103.(67. 二进制求和)题目描述:

给你两个二进制字符串 a 和 b ,以二进制字符串的形式返回它们的和。
示例 :
输入:a = "11", b = "1"
输出:"100"

第一版(用java自带的api先转为整数相加然后再转为2进制会超长,所以只能慢慢算,我写的有点啰嗦。。)

class Solution {
    public String addBinary(String a, String b) {
        StringBuilder sb=new StringBuilder();
        int lenA=a.length();
        int lenB=b.length();
        int indexA=lenA-1;
        int indexB=lenB-1;
        boolean flag=false;
        while(indexA>=0&&indexB>=0){
            if(flag){
                if(a.charAt(indexA)=='1'&&b.charAt(indexB)=='1'){
                    sb.insert(0,'1');
                }else if(a.charAt(indexA)=='1'||b.charAt(indexB)=='1'){
                    sb.insert(0,'0');
                }else{
                    sb.insert(0,'1');
                    flag=false;
                }
            }else{
                if(a.charAt(indexA)=='1'&&b.charAt(indexB)=='1'){
                    sb.insert(0,'0');
                    flag=true;
                }else if(a.charAt(indexA)=='1'||b.charAt(indexB)=='1'){
                    sb.insert(0,'1');
                }else{
                    sb.insert(0,'0');
                }
            }
            indexA--;
            indexB--;
        }
        while(indexA>=0){
            if(flag){
                if(a.charAt(indexA)=='1'){
                    sb.insert(0,'0');
                }else{
                    sb.insert(0,'1');
                    flag=false;
                }
            }else{
                if(a.charAt(indexA)=='1'){
                    sb.insert(0,'1');
                }else{
                    sb.insert(0,'0');
                }
            }
            indexA--;
        }
        while(indexB>=0){
            if(flag){
                if(b.charAt(indexB)=='1'){
                    sb.insert(0,'0');
                }else{
                    sb.insert(0,'1');
                    flag=false;
                }
            }else{
                if(b.charAt(indexB)=='1'){
                    sb.insert(0,'1');
                }else{
                    sb.insert(0,'0');
                }
            }
             indexB--;
        }
        if(flag){
            sb.insert(0,'1');
        }
        return sb.toString();
    }
}

104.(190. 颠倒二进制位)题目描述:

颠倒给定的 32 位无符号整数的二进制位。

第一版(java 有自带的 api )

public class Solution {
    // you need treat n as an unsigned value
    public int reverseBits(int n) {
        return Integer.reverse(n);
    }
}

第二版(位运算)

public class Solution {
    // you need treat n as an unsigned value
    public int reverseBits(int n) {
        int num=0;
        for(int i=1;i<=32;i++)
        {
            num<<=1;//先向左移动一位留出位置
            //取出 n 的最后一位
            int p=(n&1);
            num+=p;
            n>>=1;
        }
        return num; 
    }
}

年过完了。。亲也相完了。。回归正常!!!

  • 8
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值