(1)自我介绍。
(2)介绍自己是如何去除水印和增加水印安全性的工作,对于自己做过的项目问的很具体。
(3)让详细介绍一下逻辑回归,包括逻辑回归的分类公式,损失函数、逻辑回归分类的过程。
(4)问了一下逻辑回归中损失函数的作用?
损失函数是评价模型的一个标准,它是衡量模型的预测值和真实值之间的误差的一种评价标准。
(5)逻辑回归中除了损失函数能衡量模型的好坏,还有没有其他的方法?
哎。。。自己悟性太低啦!问到这的时候,完全不知道面试官要问啥。现在想想应该是要问精度、错误率、准确率、召回率、ROC曲线和AUC面积等衡量模型的一些标准指标。
然后,这个问题面试官就说先过去吧!接着下一道。
(6)接下来,重点来了!字节跳动中传说的手撕代码来了!
面试官问:对数据结构和算法有没有了解啊!然后直接就给了一道算法题,先说思路,然后就是现场写代码。
题目:长度为n的数组中,总是存在一个断点(下标记为i),数组中断点前面的数字是有序的,断点后的数字也是有序的,且断点后边的数字总是小于前面的数字。如果直接把断点后边的数字移动到数组的前边,那么这个数组将是有序的,具体描述如下所示。求这个数组中的第n/2大的数。
原数组: 6,8,10,13,1,2,4 找到断点移动之后的数组: 1,2,4,6,8,10 ############################# 原数组: 5,1,2,3,4, 找到断点移动之后的数组: 1,2,3,4,5 ############################## 原数组: 2,3,4,5,1 找到断点移动之后的数组: 1,2,3,4,5
我的思路:先找到断点的下标i,然后根据下标直接取出第n/2(向上取整)大的元素。
1.如果你的第n/2大的数在断点后边,那么可以直接通过下标计算得出第n/2大的数的下标。下标计算公式如下:
2.如果你的第n/2大的数在断点的前面,那么你可以把断点后边小于第n/2大的数给算上,然后在往前面查找到第n/2大的数。下标计算公式如下:
public class Main { public static void main(String[] args){ // int[] array = {6, 8, 10, 13 , 1, 2, 4}; // int[] array = {5, 1, 2, 3, 4}; int[] array = {2, 3, 4, 5, 1}; int n = array.length; int location = (int) Math.ceil(n/2.0); int index = searchIndex(array); int temp = 0; if(location <= n - index){ temp = array[index+location - 1]; }else{ temp = array[location-(n-index+1)]; } System.out.print(temp); } public static int searchIndex(int[] array){ for(int i=0; i<array.length; i++){ if(array[i] > array[i+1]){ return i + 1; } } return 0; } }
时间复杂度是O(n),空间复杂度是0。
这个算法时间复杂度是O(n),主要是在于查找断点的下标i时花费了时间。面试官让我来改进查找下标i的算法。我当时直接想出的是折半查找,面试官肯定了是折半查找算法。但是在思考用折半查找的时候,我自己遇到了两个细节问题,没有回答出来,所以这道题用折半查找没有回答出来。
遇到了两个细节问题是:
(1)我们要找数组中最小数的下标,那么我们前提是不知道最小数是多少,如何进行比较查找最小数。
(2)在折半查找的过程中,如何确定最小数是在左半边还是在右半边,换句话说,你是搜索左边的数组还是搜索右边的数组呢!
给出代码:
public class Main { public static void main(String[] args){ int[] array = {6, 8, 10, 13 , 1, 2, 4}; // int[] array = {5, 1, 2, 3, 4}; // int[] array = {2, 3, 4, 5, 1}; int n = array.length; int location = (int) Math.ceil(n/2.0); int index = Select_k(array, 0, n-1, location); System.out.print(index); } public static int quickSortOneTime(int[] array, int low, int high){ //一趟快速排序 int key = array[low]; while(low < high){ while(key < array[high] && low < high) high--; array[low] = array[high]; while(key > array[low] && low < high) low++; array[high] = array[low]; } array[high] = key; return high; } public static int Select_k(int[] array, int low, int high, int k) { int index; if(low == high) return array[low]; int partition = quickSortOneTime(array, low, high); index = high - partition + 1; //找到的是第几个大值 if(index == k) { return array[partition]; }else if(index < k) {//此时向左查找 return Select_k(array, low, partition-1, k-index); //查找的是相对位置的值,k在左段中的下标为k-index }else { return Select_k(array, partition+1, high, k); } } }
时间复杂度数O(logN)
详细介绍看我的这篇文章:
算法-在有序数组、无序数组中进行折半查找和二分法找无序数组中的第k小(大)的数
地址:https://blog.csdn.net/program_developer/article/details/80348077
共同学习,写下你的评论
评论加载中...
作者其他优质文章