《剑指offer》算法题第十天
今日题目:
- 数组中的逆序对
- 两个链表的第一个公共节点
- 数字在排序数组中出现的次数
- 二叉搜索树的第k大节点
- 字符流中第一个不重复的字符
1. 数组中的逆序对
题目描述:
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。 思路:
这道题运用归并排序的思想来求解,归并排序是面试中经常问到的知识点,得经常翻出来熟悉熟悉。
代码如下:
public class Solution {
int cnt; public int InversePairs(int[] array) {
cnt = 0;
if (array != null)
mergeSortUp2Down(array, 0, array.length - 1);
return cnt;
} /*
* 归并排序(从上往下)
*/
public void mergeSortUp2Down(int[] a, int start, int end) {
if (start >= end)
return;
int mid = (start + end) >> 1; mergeSortUp2Down(a, start, mid);
mergeSortUp2Down(a, mid + 1, end); merge(a, start, mid, end);
} /*
* 将一个数组中的两个相邻有序区间合并成一个
*/
public void merge(int[] a, int start, int mid, int end) {
int[] tmp = new int[end - start + 1]; int i = start, j = mid + 1, k = 0;
while (i <= mid && j <= end) {
if (a[i] <= a[j])
tmp[k++] = a[i++];
else {
tmp[k++] = a[j++];
cnt += mid - i + 1; // core code, calculate InversePairs............
cnt %= 1000000007;
}
} while (i <= mid)
tmp[k++] = a[i++];
while (j <= end)
tmp[k++] = a[j++];
for (k = 0; k < tmp.length; k++)
a[start + k] = tmp[k];
}
}
2.两个链表中的第一个公共节点
题目描述:
输入两个链表,找出它们的第一个公共结点。 思路:
《剑指offer》中的参考答案利用了两个栈来分别存储两个链表,然后从链尾到链头遍历两个链表,寻找公共的节点。但是博主觉得没必要那么麻烦,运用一个hashset就能够处理这道题。
另外,在这道题的讨论区中,有一个特别精妙的方法,利用两个指针遍历数组,第一趟得到链表长度的差值,第二趟寻找公共节点,下面也会贴出来。
代码如下:
//利用hashset
import java.util.HashSet;
public class Solution {
public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
if(pHead1 == null || pHead2 == null) return null;
HashSet<ListNode> set = new HashSet();
while(pHead1 != null){
set.add(pHead1);
pHead1 = pHead1.next;
}
while(pHead2 != null){
if(set.contains(pHead2))
return pHead2;
pHead2 = pHead2.next;
}
return null;
}
} //两个指针的方法
public class Solution {
public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
ListNode p1 = pHead1;
ListNode p2 = pHead2;
while(p1 != p2){
p1 = (p1==null ? pHead2 : p1.next);
p2 = (p2==null ? pHead1 : p2.next);
}
return p1;
}
}
3.数字在排序数组中出现的次数
题目描述:
统计一个数字在排序数组中出现的次数。 思路:
比较直接的方法是直接遍历数组,统计目标数字出现的次数,时间复杂度为O(n)。
比较快的方法是利用二分查找的思想,时间复杂度可达到O(logn)。
代码如下:
public class Solution {
int count = 0;
public int GetNumberOfK(int [] array , int k) {
binSearch(array,k,0,array.length-1);
return count;
} public void binSearch(int[] nums,int k,int start,int end){
if(start == end){
if(nums[start] == k) count++;
return;
}else if(start < end){
int mid = (start+end)/2;
if(nums[mid] == k){
count++;
binSearch(nums,k,start,mid-1);
binSearch(nums,k,mid+1,end);
}else if(nums[mid] < k){
binSearch(nums,k,mid+1,end);
}else{
binSearch(nums,k,start,mid-1);
}
}
}
}
4.二叉搜索树的第k大节点
题目描述:
给定一颗二叉搜索树,请找出其中的第k大的结点。例如, 5 / \ 3 7 /\ /\ 2 4 6 8 中,按结点数值大小顺序第三个结点的值为4。 思路:
比较直接,二叉树的中序遍历。不过需要提一下的是,二叉树三种遍历顺序的递归和迭代实现方式都得非常熟悉。
代码如下:
import java.util.Stack;
public class Solution {
TreeNode KthNode(TreeNode pRoot, int k){
if(pRoot == null || k == 0) return null;
Stack<TreeNode> stack = new Stack();
int count = 0;
while(pRoot != null || !stack.isEmpty()){
if(pRoot != null){
stack.push(pRoot);
pRoot = pRoot.left;
}else{
pRoot = stack.pop();
count++;
if(count == k)
return pRoot;
pRoot = pRoot.right;
}
}
return null;
}
}
5.字符流中第一个不重复的字符
题目描述:
请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符“google"时,第一个只出现一次的字符是"l"。 思路:
这道题和之前的求一个数据流中的中位数的题相似,重点是如何选择一个合适的数据结构来存储数据,是的插入和查询的效率都比较高。
在这道题中,《剑指offer》给的参考答案是声明一个int型的数组来存储各个字符的状态。这种思想非常地重要,应多做练习来熟悉。
代码如下:
public class Solution {
//Insert one char from stringstream
int[] map = new int[256];
int index = 1;
public void Insert(char ch)
{//0代表还未出现相应的字符,-1代表出现一次以上,其他数字代表什么时候出现
if(map[ch] == 0)
map[ch] = index;
else if(map[ch] > 0)
map[ch] = -1;
index ++;
}
//return the first appearence once char in current stringstream
public char FirstAppearingOnce()
{
int min = Integer.MAX_VALUE;
int ind = -1;
for(int i = 0; i < 256; i++){//找出大于0的最小值及其坐标
if(map[i] > 0 && map[i] < min){
min = map[i];
ind = i;
}
}
if(ind == -1)//不存在大于0的数,则没有字符出现一次
return '#';
else
return (char)ind;
}
}
《剑指offer》算法题第十天的更多相关文章
- 剑指offer算法题
数组中只出现一次的数字(一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字): 解法在于位运算中的异或,直接异或可以得到这两个数的异或,按照最后的有效数字位可以 ...
- 剑指offer算法总结
剑指offer算法学习总结 节选剑指offer比较经典和巧妙的一些题目,以便复习使用.一部分题目给出了完整代码,一部分题目比较简单直接给出思路.但是不保证我说的思路都是正确的,个人对算法也不是特别在行 ...
- 剑指Offer——算法复杂度中的O(logN)底数是多少
剑指Offer--算法复杂度中的O(logN)底数是多少 前言 无论是计算机算法概论.还是数据结构书中,关于算法的时间复杂度很多都用包含O(logN)这样的描述,但是却没有明确说logN的底数究竟是多 ...
- 剑指 offer 第一题: 二维数组中的查找
打算写 图解剑指 offer 66 题 的系列文章,不知道大家有没有兴趣
- 剑指Offer编程题2——替换空格
剑指Offer编程题2——替换空格 题目描述 请实现一个函数,将一个字符串中的每个空格替换成“%20”.例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happ ...
- 剑指Offer编程题1——二维数组中的查找
剑指Offer编程题1---------------二维数组中的查找 题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完 ...
- 剑指offer编程题66道题 36-66
36.两个链表的第一个公共节点 题目描述 输入两个链表,找出它们的第一个公共结点. 1.具有重合节点的两个链表是一个Y字性,用两个堆栈放这两个链表,从尾部开始遍历,直到遍历到最后一个重合节点. 这种算 ...
- 牛客网剑指offer刷题总结
二维数组中的查找: 题目描述:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 两 ...
- LeetCode剑指Offer刷题总结(一)
LeetCode过程中值得反思的细节 以下题号均指LeetCode剑指offer题库中的题号 本文章将每周定期更新,当内容达到10题左右时将会开下一节. 二维数组越界问题04 public stati ...
- 剑指offer编程题Java实现——面试题11数值的整数次方
题目: 实现函数double power(double base,int exponent),求base的exponent次方.不得使用库函数,同时不需要考虑大数问题. 解题思路:最一般的方法实现数值 ...
随机推荐
- TensorFlow实现一个简单线性回归的例子
__author__ = "WSX" import tensorflow as tf import numpy as np import matplotlib.pyplot as ...
- 怎样在 Vue 中使用 v-model 实现双向数据绑定?
1. 所谓 双向数据绑定, 可以理解为: 修改 A , B 会跟着被修改, 修改 B , A 会跟着被修改. 常用在需要 进行用户输入的地方, 比如 这些 html 标签: input.select ...
- 《深入实践C++模板编程》之二——模板类
1.类的模板的使用 类,由于没有参数,所以没有模板实参推导机制. #include <stdexcept> template<typename T> class my_stac ...
- shiro学习(三,shiro加密)
shiro加密 使用MD5加密 认证 //自定义的Realm 域 public class CustomRealmSecret extends AuthorizingRealm { @Overrid ...
- 导入java web项目时 web.xml第一行报错
报错信息: Referenced file contains errors (http://java.sun.com/xml/ns/j2ee/j2ee_1_4.xsd). For more infor ...
- Linux之curl
简介 curl 是常用的命令行工具,用来请求 Web 服务器.它的名字就是客户端(client)的 URL 工具的意思. 它的功能非常强大,命令行参数多达几十种.如果熟练的话,完全可以取代 Postm ...
- npm install 常用的几个参数
npm install moduleName # 安装模块到项目目录下 npm install -g moduleName # -g 的意思是将模块安装到全局,具体安装到磁盘哪个位置,要看 npm c ...
- Delphi10.2.3利用THttpClient实现http异步下载
随着Delphi 10.2.3的发布,随之带来更稳定.更完善的版本.今天借官方的例子,解读一下如何实现Http异步下载并显示下载进度. 使用的核心组件是THttpClient,首先建立一个THttpC ...
- beego注解路由不刷新(不生效)
本文主要说明本人在使用beego的注解路由时不生效问题 背景: 1.按照官网进行注解路由配置,第一次设置路由,完全正确,注解路由可用. 2.修改路由注释后,发现swagger页面并未有对应的更新 3. ...
- linux--mysql 8.0.16--裸机安装
参考: https://www.cnblogs.com/warmsmile/p/10210739.html https://www.cnblogs.com/yg_zhang/p/10424926.ht ...