算法面试题

快手面试题 

题目描述

博主的思路: 先用一个集合list,存储0的下标,然后依次判断,这些0所在的位置能否种花,若能,则将flowerbed对应位置改为1;

具体代码: 

class Solution {
    public boolean canPlaceFlowers(int[] flowerbed, int n) {
        if(n==0){
            return true;
        }
        if(flowerbed.length==1&&flowerbed[0]==0&&n==1){
            return true;
        }
         if(flowerbed.length==1&&flowerbed[0]==0&&n>1){
            return false;
        }
         if(flowerbed.length==1&&flowerbed[0]==1&&n>=1){
            return false;
        }
        
        List<Integer> list=new ArrayList<Integer>();
        int count=0;
        for(int i=0;i<flowerbed.length;i++){
            if(flowerbed[i]==0){
                list.add(i);
            }
        }
         if(list.get(0)==0&&flowerbed[list.get(0)+1]==0){
                flowerbed[0]=1;
                count++;
            }
        for(int i=1;i<list.size();i++){
            if(flowerbed[list.get(i)-1]==0&&list.get(i)!=flowerbed.length-1&&flowerbed[list.get(i)+1]==0){
                flowerbed[list.get(i)]=1;
                count++;
            }else if(list.get(i)==flowerbed.length-1&&flowerbed[list.get(i)-1]==0){
                flowerbed[list.get(i)]=1;
                count++;
            }
        }
        return count>=n;     }
}

前面的代码写的不太美观,修正下

class Solution {
    public boolean canPlaceFlowers(int[] flowerbed, int n) {
       /*
       分析题意:判断每个位置能否种花,要看他的前置结点和后置结点是否为0,有的话此节点可以种花
       存在两个特殊的情况,如果是第一个位置的话,则只需要判断后置结点是否为0即可,
       如果是最后一个位置,只需要判断前置结点是否为0即可,但是我们为了保证判断条件的一致性,
       所以第一个花盆,让他的前置结点直接给0.最后一个花盆,后置结点直接给0
       */
        int size=flowerbed.length;
        for (int i=0;i<size;i++){
           if (flowerbed[i]==1){
               continue;
           }
        //如果当前位置为0 则判断其前置结点和后置结点是否为0
            int pre=i==0?0:flowerbed[i-1];
           int next=i==(size-1)?0:flowerbed[i+1];
           if (pre==0&&next==0){
               flowerbed[i]=1;
               n--;
           }
        }
    return n<=0;}
}

628. 三个数的最大乘积

题目描述: 

思路:

通过归纳不难分析出,数组有五种情况

第一种:全正  最大为后三个相乘 

第二种:全负  最大为后三个相乘 

第三种:一个正  最大为前两个和最后一个相乘

第四种:两个正  最大为后三个或者前两个和最后一个相乘

第五种:三个正及以上 最大为后三个相乘或者前两个和最后一个相乘

总结发现,一个数组三个数的最大乘积,要么是数组的后三个乘积之和,要么是前两个和最后一个相乘。

方法一具体代码

class Solution {
    public int maximumProduct(int[] nums) {
        Arrays.sort(nums);
        int n=nums.length;  
 return   Math.max(nums[0]*nums[1]*nums[n-1],nums[n-1]*nums[n-2]*nums[n-3]);
    }
}

方法二

线性扫描

在方法一中,我们实际上只要求出数组中最大的三个数以及最小的两个数,因此我们可以不用排序,用线性扫描直接得出这五个数。

具体代码

class Solution {
    public int maximumProduct(int[] nums) {
        // 最小的和第二小的
        int min1 = Integer.MAX_VALUE, min2 = Integer.MAX_VALUE;
        // 最大的、第二大的和第三大的
        int max1 = Integer.MIN_VALUE, max2 = Integer.MIN_VALUE, max3 = Integer.MIN_VALUE;

        for (int x : nums) {
            if (x < min1) {
                min2 = min1;
                min1 = x;
            } else if (x < min2) {
                min2 = x;
            }

            if (x > max1) {
                max3 = max2;
                max2 = max1;
                max1 = x;
            } else if (x > max2) {
                max3 = max2;
                max2 = x;
            } else if (x > max3) {
                max3 = x;
            }
        }

        return Math.max(min1 * min2 * max1, max1 * max2 * max3);
    }
}

字节面试题 

剑指 Offer 35. 复杂链表的复制

题目描述

方法一:哈希表+迭代

 

 具体代码

class Solution {
    public Node copyRandomList(Node head) {
        if(head == null) return null;
        Node cur = head;
        Map<Node, Node> map = new HashMap<>();
        // 3. 复制各节点,并建立 “原节点 -> 新节点” 的 Map 映射
        while(cur != null) {
            map.put(cur, new Node(cur.val));
            cur = cur.next;
        }
        cur = head;
        // 4. 构建新链表的 next 和 random 指向
        while(cur != null) {
            map.get(cur).next = map.get(cur.next);
            map.get(cur).random = map.get(cur.random);
            cur = cur.next;
        }
        // 5. 返回新链表的头节点
        return map.get(head);
    }
}

方法二:哈希表+回溯

 

具体代码

class Solution {
    Map<Node, Node> cachedNode = new HashMap<Node, Node>();

    public Node copyRandomList(Node head) {
        if (head == null) {
            return null;
        }
        if (!cachedNode.containsKey(head)) {
            Node headNew = new Node(head.val);
            cachedNode.put(head, headNew);
            headNew.next = copyRandomList(head.next);
            headNew.random = copyRandomList(head.random);
        }
        return cachedNode.get(head);
    }
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值