0
点赞
收藏
分享

微信扫一扫

微软实习生面试的2道算法题目——20220119

朱悟能_9ad4 2022-01-20 阅读 198

微软实习生面试的2道算法题目

题目一

题目一有点类似于leetcode中的旋转数组那一系列题目https://leetcode-cn.com/problems/search-rotate-array-lcci/solution/xuan-zhuan-shu-zu-cong-yi-dao-nan-ge-ge-dcv7a/,考察二分。面试官将题目变形为V型或倒V数组找最小值的下标,具体题目如下。

  • 题目:在一个数组中,元素是有序的,至多出现一个拐点,让我们求出数组中的最小值的下标。
  • 对题目理解:题目是面试官口述,有些具体细节可以自己加上,我的理解主要就是分为4中情况,数组是单调递增、单调递减、凹型的V数组,凸型的倒V数组。室友和面试管交流过程中,让其查找的时间复杂度O(nlogn)——>O(n)——>O(logn),也就是最终要使用二分的方法做出来。我的理解是先判断出事以上4种情况的哪一个,然后进行处理,单调递增、单调递减、凸型的倒V数组这3种情况是可以直接得到答案,关键在于凹型的V数组的查找。我的做法是使用二分逼近最低点,如果mid在最低点直接返回,如果mid在左边下坡的,则令left=mid+1继续查找。如果mid在右边下坡的,则令right=mid-1继续查找,直到right等于left返回结果。
  • 代码(Java)
public class Main {
    public static void main(String[] args) {
        int[] arr={4,2,3};
        int len=arr.length-1;
        if(len<3) System.out.println(arr[0]<arr[1]?0:1);
        //判断凹凸性和线性的关系
        if(arr[1]>arr[0]&&arr[len]>arr[len-1]){  //单调递增
            System.out.println(0);
        }else if(arr[1]<arr[0]&&arr[len]<arr[len-1]){  //单调递减
            System.out.println(len);
        }else if(arr[1]>arr[0]&&arr[len]<arr[len-1]){  //凸的
            System.out.println(arr[0]<arr[len]?0:len);
        }else if(arr[1]<arr[0]&&arr[len]>arr[len-1]){  //凹的
            int left=0,right=len;
            while (left<right){
                int mid=left+(right-left)/2;
                if(arr[mid]<arr[mid-1]&&arr[mid]<arr[mid+1]){
                    System.out.println(mid);
                    return;
                }else if(arr[mid]<arr[mid-1]&&arr[mid]>arr[mid+1]){
                    left=mid+1;
                }else if(arr[mid]>arr[mid-1]&&arr[mid]<arr[mid+1]){
                    right=mid-1;
                }
            }
            System.out.println(left);
        }
    }
}

题目二

  • 二叉树中的最大路径和(leetcode中的原题https://leetcode-cn.com/problems/binary-tree-maximum-path-sum/,难度hard)
    路径 被定义为一条从树中任意节点出发,沿父节点-子节点连接,达到任意节点的序列。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点,且不一定经过根节点。
    路径和 是路径中各节点值的总和。
    给你一个二叉树的根节点 root ,返回其 最大路径和 。
    在这里插入图片描述
  • 思路解法:
    主要就是运用自底向上的递归的方法,自底向上的计算二叉树中的每一个节点的最大贡献值,并更新全局最大值。具体而言,就是在以该节点为根节点的子树中寻找以该节点为起点的一条路径,使得该路径上的节点值之和最大。
    具体详细思路可以参考题解:https://leetcode-cn.com/problems/binary-tree-maximum-path-sum/solution/er-cha-shu-zhong-de-zui-da-lu-jing-he-by-leetcode-/
  • 代码(Java):
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    int maxSum=Integer.MIN_VALUE;
    public int maxPathSum(TreeNode root) {
        //递归解法,该递归函数返回的
        maxValue(root);
        return maxSum;
    }
    public int maxValue(TreeNode node){
        if(node==null){
            return 0;
        }
        //递归计算左右子节点的最大贡献值,只有在最大贡献值大于 0 时,才会选取对应子节点
        int leftValue=Math.max(maxValue(node.left),0);
        int rightValue=Math.max(maxValue(node.right),0);
        //节点的最大路径和取决于该节点的值、该节点的左右子节点的最大贡献值
        int lmr=node.val+leftValue+rightValue;
        int ret=node.val+Math.max(leftValue,rightValue);
        maxSum=Math.max(maxSum,Math.max(lmr,ret));
        return ret;
    }
}
举报

相关推荐

0 条评论