今日题目(对应书上第39~42题):

  1. 数组中出现次数超过一半的数字
  2. 最小的k个数(top k,重点!)
  3. 数据流中的中位数
  4. 连续子数组的最大和

今天的题目都比较经典,特别是第2题。

1. 数组中出现次数超过一半的数字

题目描述:
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。 思路:
有两种方法,
一,利用类似于快排的思想,寻找数组中的中位数,然后再检查是否满足出现次数。
二,根据数组的特点来做。

代码如下:

 //方法一,快排
public class Solution {
public int MoreThanHalfNum_Solution(int [] array) {
if(array.length == 0) return 0;
int start = 0, end = array.length-1;
int mid = array.length>>1;
while(start < end){
int ind = partition(array,start,end);
if(ind == mid)
break;
if(ind > mid)
end = ind-1;
if(ind < mid)
start = ind+1;
}
if(check(array,array[mid]))
return array[mid];
else return 0;
} public boolean check(int[] nums,int result){
int times = 0;
for(int n:nums){
if(n == result)
times++;
}
return times*2 > nums.length;
} public int partition(int[] nums,int start,int end){
int target = nums[end];
int res = start;
for(int i = start; i < end; i++){
if(nums[i] < target){
int swap = nums[i];
nums[i] = nums[res];
nums[res] = swap;
res++;
}
}
nums[end] = nums[res];
nums[res] = target;
return res;
}
} //方法二
public int MoreThanHalfNum_Solution(int [] array) {
if(array.length == 0) return 0;
int result = array[0];
int times = 1;
for(int n:array){
if(times == 0){
result = n;
times = 1;
}else if(result == n)
times++;
else
times--;
}
if(check(array,result))
return result;
else return 0;
}

2. 最小的k个数

题目描述:
输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。 思路:
这道题是经典的top K问题,有两种解法:
1,运用快排,找出第K个数的位置,将前面的数输出
2,利用容量为K的最大堆,循环数组,每次替换掉堆中最大的数

代码如下:

 //快排
public class Solution {
public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
ArrayList<Integer> res = new ArrayList();
if(k > input.length || k == 0) return res;
int start = 0, end = input.length-1;
int ind = partition(input,start,end);
while(ind != k-1){
if(ind > k-1){
end = ind-1;
}else{
start = ind+1;
}
ind = partition(input,start,end);
}
for(int i = 0;i < k; i++)
res.add(input[i]);
return res;
} public int partition(int[] nums,int start,int end){
int target = nums[end];
int ind = start;
for(int i = start; i < end;i++){
if(nums[i] < target){
int swap = nums[i];
nums[i] = nums[ind];
nums[ind] = swap;
ind++;
}
}
nums[end] = nums[ind];
nums[ind] = target;
return ind;
}
} //利用最大堆
public class Solution {
public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
if(k > input.length || k < 1) return new ArrayList();
PriorityQueue<Integer> maxHeap = new PriorityQueue(k,new Comparator<Integer>(){
public int compare(Integer o1,Integer o2){
return o2.compareTo(o1);
}
});
for(int i = 0; i < input.length; i++){
if(maxHeap.size() < k)
maxHeap.add(input[i]);
else{
if(maxHeap.peek() > input[i]){
maxHeap.poll();
maxHeap.add(input[i]);
}
}
}
return new ArrayList(maxHeap);
}
}

3.数据流中的中位数

题目描述:
如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。 思路:
这道题的关键是选择一个怎样的数据结构来维护数据流,可以使插入和查询的速度都比较理想。在这边维护了一个最大堆和一个最小堆,最大堆存储中位数左边的数字,最小堆存储中位数右边的数字。

代码如下:

 public class Solution {
int count = 0;
PriorityQueue<Integer> min = new PriorityQueue();
PriorityQueue<Integer> max = new PriorityQueue(new Comparator<Integer>(){
public int compare(Integer o1,Integer o2){
return o2-o1;
}
});
public void Insert(Integer num) {
if((count&1) == 0){
min.offer(num);
max.offer(min.poll());
}else{
max.offer(num);
min.offer(max.poll());
}
count++;
} public Double GetMedian() {
if(((min.size()+max.size())&1) == 0)
return (min.peek()+max.peek())/2.0;
else
return max.peek()*1.0;
}
}

4.连续子数组的最大和

题目描述:
输入一个整数数组,数组里有正数也有负数。数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为O(n)。 思路:
这道题也算是比较经典的一道题了,面经里面经常看到,下面给出两种解法。

代码如下:

 //解法一
public class Solution {
public int FindGreatestSumOfSubArray(int[] array) {
int max = Integer.MIN_VALUE;
int sum = 0;
for(int n:array){
if(sum <= 0)
sum = n;
else
sum += n;
max = max>sum?max:sum; }
return max;
}
} //解法二,动态规划
public class Solution {
public int FindGreatestSumOfSubArray(int[] array) {
int[] dp = new int[array.length];
dp[0] = array[0];
for(int i = 1; i < array.length; i++){
if(dp[i-1] < 0)
dp[i] = array[i];
else
dp[i] = array[i] + dp[i-1];
}
int res = dp[0];
for(int n:dp)
res = n>res?n:res;
return res;
}
}

《剑指offer》算法题第八天的更多相关文章

  1. 剑指offer算法题

    数组中只出现一次的数字(一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字): 解法在于位运算中的异或,直接异或可以得到这两个数的异或,按照最后的有效数字位可以 ...

  2. 剑指offer算法总结

    剑指offer算法学习总结 节选剑指offer比较经典和巧妙的一些题目,以便复习使用.一部分题目给出了完整代码,一部分题目比较简单直接给出思路.但是不保证我说的思路都是正确的,个人对算法也不是特别在行 ...

  3. 剑指Offer——算法复杂度中的O(logN)底数是多少

    剑指Offer--算法复杂度中的O(logN)底数是多少 前言 无论是计算机算法概论.还是数据结构书中,关于算法的时间复杂度很多都用包含O(logN)这样的描述,但是却没有明确说logN的底数究竟是多 ...

  4. 剑指 offer 第一题: 二维数组中的查找

    打算写 图解剑指 offer 66 题 的系列文章,不知道大家有没有兴趣

  5. 剑指Offer编程题2——替换空格

    剑指Offer编程题2——替换空格 题目描述 请实现一个函数,将一个字符串中的每个空格替换成“%20”.例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happ ...

  6. 剑指Offer编程题1——二维数组中的查找

    剑指Offer编程题1---------------二维数组中的查找 题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完 ...

  7. 剑指offer编程题66道题 36-66

    36.两个链表的第一个公共节点 题目描述 输入两个链表,找出它们的第一个公共结点. 1.具有重合节点的两个链表是一个Y字性,用两个堆栈放这两个链表,从尾部开始遍历,直到遍历到最后一个重合节点. 这种算 ...

  8. 牛客网剑指offer刷题总结

    二维数组中的查找: 题目描述:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 两 ...

  9. LeetCode剑指Offer刷题总结(一)

    LeetCode过程中值得反思的细节 以下题号均指LeetCode剑指offer题库中的题号 本文章将每周定期更新,当内容达到10题左右时将会开下一节. 二维数组越界问题04 public stati ...

  10. 剑指offer编程题Java实现——面试题11数值的整数次方

    题目: 实现函数double power(double base,int exponent),求base的exponent次方.不得使用库函数,同时不需要考虑大数问题. 解题思路:最一般的方法实现数值 ...

随机推荐

  1. 【NOIP2015普及组】 推销员(纪中数据-标准)

    题目 [题目描述] 阿明是一名推销员,他奉命到螺丝街推销他们公司的产品.螺丝街是一条死胡同,出口与入口是同一个,街道的一侧是围墙,另一侧是住户.螺丝街一共有 N 家住户,第 i 家住户到入口的距离为 ...

  2. XOR Guessing(交互题+思维)Educational Codeforces Round 71 (Rated for Div. 2)

    题意:https://codeforc.es/contest/1207/problem/E 答案guessing(0~2^14-1) 有两次机会,内次必须输出不同的100个数,每次系统会随机挑一个你给 ...

  3. package[golang]学习笔记之context

    *关于context https://talks.golang.org/2014/gotham-context.slide#29

  4. Codeforces 1189D2. Add on a Tree: Revolution

    传送门 首先可以证明一颗树合法的充分必要条件是不存在某个节点的度数为 $2$ 首先它是必要的,考虑任意一条边连接的两点如果存在某一点 $x$ 度数为 $2$ ,那么说明 $x$ 还有连一条边出去,那么 ...

  5. yolov3应该什么时候停止训练?

    按照训练期间的参数提示: Region Avg IOU:0.798363,Class:0.893232,Obj:0.700808,No Obj:0.004567,Avg Recall:1.000000 ...

  6. 客户端注册Cannot execute request on any known server解决

    在对eureka注册中心服务端添加安全验证后,新版本springcloud出现一个问题就是,在客户端注册到服务中心时报了一个错:Cannot execute request on any known ...

  7. 帝国cms列表内容模板加上数字编号

    /*这个[!--no.num--]指的是信息编号.每次增加1*/ <li data-eq="[!--no.num--]"> <div class="ti ...

  8. 浅谈RPC框架

    RPC(Remote Promote Call) RPC(Remote Promote Call):一种进程间通信方式.允许像调用本地服务一样调用远程服务. RPC框架的主要目标就是让远程服务调用更简 ...

  9. flutter: Another exception was thrown: Navigator operation requested with a context that does not include a Navigator.

    import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends State ...

  10. MySQL数据库笔记二:数据类型及数据库操作

    三.MySQL数据库数据类型 MySQL数据库中支持多种数据类型:数值型.字符型.日期型 常用的数据类型: 1.整型 int:整形,存储整数 int(M):M表示预期值.与存储大小和数值的范围无关. ...