37.数字在排序数组中出现的次数

统计一个数字在排序数组中出现的次数。

采用二分查找法

/*
方法一:时间复杂度O(n),不可选
*/ public class Solution {
public int GetNumberOfK(int [] array , int k) {
if(array.length == 0) return 0;
int count = 0;
for(int i = 0 ; i < array.length ; i++){
if(array[i] == k){
count++;
}else{
if(count != 0)
break;
}
}
return count;
}
} /*
方法二:首选!先采用二分查找法,在数组中查找到第一个K和第二个K,总时间复杂度O(logn)
*/
public class Solution {
public int GetNumberOfK(int[] array,int k){
if(array.length == 0) return 0;
int first = getFirstK(array,k,0,array.length-1);
int last = getLastK(array,k,0,array.length-1);
if(first > -1 && last > -1)
return last - first + 1;
return 0;
}
public int getFirstK(int[] array,int k,int start,int end){
if(start > end) return -1;
int midIdx = (end + start)/2;
if(array[midIdx] == k){
if((midIdx > 0 && array[midIdx-1] != k) || midIdx == 0)
return midIdx;
else{
end = midIdx - 1;
return getFirstK(array,k,start,end);
}
}else if(array[midIdx] > k){
end = midIdx - 1;
}else if(array[midIdx] < k){
start = midIdx +1;
}
return getFirstK(array,k,start,end);
}
public int getLastK(int[] array,int k ,int start,int end){
if(start > end) return -1;
int midIdx = (start + end)/2;
if(array[midIdx] == k){
if((midIdx < array.length-1 && array[midIdx+1] != k) || midIdx == array.length-1)
return midIdx;
else
start = midIdx + 1;
}else if(array[midIdx] > k){
end = midIdx - 1;
}else if(array[midIdx] < k){
start = midIdx + 1;
}
return getLastK(array,k,start,end);
}
}

38.二叉树的深度

输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。

/**
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null; public TreeNode(int val) {
this.val = val; } }
*/
public class Solution {
public int TreeDepth(TreeNode root) {
if(root == null) return 0;
int left = TreeDepth(root.left);
int right = TreeDepth(root.right);
if(left>right) return left+1;
else return right+1;
}
}

39.平衡二叉树

输入一棵二叉树,判断该二叉树是否是平衡二叉树。如果某二叉树中任意节点的左、右子树的深度相差不超过1,那么他就是一棵平衡二叉树。

解法一:不够简便

public class Solution {
public boolean IsBalanced_Solution(TreeNode root) {
if(root == null) return true;
int left = TreeDepth(root.left);
int right = TreeDepth(root.right);
if((left-right)>1||(left-right)<-1)
return false;
else
return IsBalanced_Solution(root.left) && IsBalanced_Solution(root.right);
}
public int TreeDepth(TreeNode root){
if(root == null) return 0;
int left = TreeDepth(root.left);
int right = TreeDepth(root.right);
return left > right ? left+1 : right+1;
}
}

解法二:推荐!后序遍历二叉树,只需遍历一遍即可。

public class Solution {
public boolean IsBalanced_Solution(TreeNode root) {
return getDepth(root) != -1;
}
public int getDepth(TreeNode root){
if(root == null) return 0;
int left = getDepth(root.left);
if(left == -1)
return -1;
int right = getDepth(root.right);
if(right == -1)
return -1;
return Math.abs(left-right) > 1 ? -1 : Math.max(left,right) + 1;
}
}

40.数组中只出现一次的数字

一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。

第一种:利用Set,空间复杂度为O(N)

//num1,num2分别为长度为1的数组。传出参数
//将num1[0],num2[0]设置为返回结果
import java.util.HashSet;
import java.util.Iterator;
public class Solution {
public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
HashSet<Integer> set = new HashSet<Integer>();
for(int i = 0;i<array.length;i++){
if(set.contains(array[i])){
set.remove(array[i]);
}else{
set.add(array[i]);
}
}
boolean isFirst = true;
Iterator iter = set.iterator();
while(iter.hasNext()){
if(isFirst){
num1[0] = (int)iter.next();
isFirst = false;
}else
num2[0] = (int)iter.next();
}
}
}

41.数组中只出现一次的数字

一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。

按位运算:异或、位移

//num1,num2分别为长度为1的数组。传出参数
//将num1[0],num2[0]设置为返回结果
public class Solution {
public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
int OR = 0;
for(int i = 0;i<array.length;i++)
OR ^= array[i];
int idx = 0;//OR从后数第几位是1,从1开始
while(OR != 0){
OR = OR >> 1;
idx++;
}
num1[0] = 0;
num2[0] = 0;
for(int i = 0;i<array.length;i++){
if((array[i]&(1<<(idx-1))) == 0)
num1[0] ^= array[i];
else
num2[0] ^= array[i];
}
}
}

42.和为S的连续正数序列

小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100。但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数)。没多久,他就得到另一组连续正数和为100的序列:18,19,20,21,22。现在把问题交给你,你能不能也很快的找出所有和为S的连续正数序列? Good Luck!

输出描述:

输出所有和为S的连续正数序列。序列内按照从小至大的顺序,序列间按照开始数字从小到大的顺序

import java.util.ArrayList;
public class Solution {
public ArrayList<ArrayList<Integer> > FindContinuousSequence(int sum) {
ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();
int small = 1,big = 2,listSum = 3;
int mid = (sum+1)/2;
while(small < mid && small < big){
if(listSum == sum){ //注意此处很容易出现死循环,当检测出一个序列后,记得变化small数值
ArrayList<Integer> listResult = new ArrayList<>();
for(int i = small;i <= big;i++)
listResult.add(i);
result.add(listResult);
listSum -= small;
small++;
}else if(listSum < sum){
big++;
listSum += big;
}else if(listSum > sum){
listSum -= small;
small++;
}
}
return result;
}
}

43.和为S的两个数

输入一个递增排序的数组和一个数字S,在数组中查找两个数,是的他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。

解析:

其实找的就是数组最两侧满足和为S的数字,因为:

z=xy

x+y=s

z=x(s-x)=sx-x^2 函数图像为向下开口的抛物线,两段数值小中间大。所以取两边的值。

import java.util.ArrayList;
public class Solution {
public ArrayList<Integer> FindNumbersWithSum(int [] array,int sum) {
ArrayList<Integer> result = new ArrayList<>();
int p1 = 0,p2 = array.length-1;
while(p1<p2){
if(array[p1]+array[p2] == sum){
result.add(array[p1]);
result.add(array[p2]);
return result;
}else if(array[p1]+array[p2]>sum)
p2--;
else
p1++;
}
return result;
}
}

44.坐旋转字符串

汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果。对于一个给定的字符序列S,请你把其循环左移K位后的序列输出。例如,字符序列S=”abcXYZdef”,要求输出循环左移3位后的结果,即“XYZdefabc”。是不是很简单?OK,搞定它!

该题有好多种做法

方法一:虽然AC,但是不是最优解

public class Solution {
public String LeftRotateString(String str,int n) {
if(n<0 || str==null || str.length() == 0) return "";
n %= str.length();
StringBuilder sb = new StringBuilder();
for(int i = n;i<str.length();i++){
sb.append(str.charAt(i));
}
for(int i = 0;i<n;i++){
sb.append(str.charAt(i));
}
return sb.toString();
}
}

方法二

public class Solution {
public String LeftRotateString(String str,int n) {
if(n<0 || str==null || str.length() == 0) return "";
n %= str.length();
StringBuilder sb = new StringBuilder();
for(int i = n;i<str.length();i++){
sb.append(str.charAt(i));
}
for(int i = 0;i<n;i++){
sb.append(str.charAt(i));
}
return sb.toString();
}
}

45.翻转字符串

牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上。同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意思。例如,“student. a am I”。后来才意识到,这家伙原来把句子单词的顺序翻转了,正确的句子应该是“I am a student.”。Cat对一一的翻转这些单词顺序可不在行,你能帮助他么?

public class Solution {
public String ReverseSentence(String str) {
if(str.length()==0) return "";
char[] charArray = str.toCharArray();
Reverse(charArray,0,str.length()-1);
int start = 0,end = 0;
for(int i = 0;i < charArray.length;i++){
if(charArray[i] == ' '){
end = i-1;
Reverse(charArray,start,end);
start = i+1;
}
}
Reverse(charArray,start,charArray.length-1);
return String.valueOf(charArray);
}
public char[] Reverse(char[] charArray,int start,int end){
while(start<end){
char temp = charArray[start];
charArray[start] = charArray[end];
charArray[end] = temp;
start++;
end--;
}
return charArray;
}
}

剑指offer 第十天的更多相关文章

  1. 剑指Offer(十八):二叉树的镜像

    剑指Offer(十八):二叉树的镜像 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.net/baidu ...

  2. 剑指Offer(十九):顺时针打印矩阵

    剑指Offer(十九):顺时针打印矩阵 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.net/baid ...

  3. 剑指offer三十五之数组中的逆序对

    一.题目 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数P.并将P对1000000007取模的结果输出. 即输出P%1000 ...

  4. 剑指offer五十二之正则表达式匹配

    一.题目 请实现一个函数用来匹配包括'.'和'*'的正则表达式.模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(包含0次). 在本题中,匹配是指字符串的所有字符匹配整个模式 ...

  5. 剑指offer二十二之从上往下打印二叉树

    一.题目 从上往下打印出二叉树的每个节点,同层节点从左至右打印. 二.思路 二叉树的层次遍历,可以借助队列实现.具体思路详见注释. 三.代码 import java.util.ArrayList; i ...

  6. 剑指Offer(十九)——顺时针打印矩阵

    题目描述 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字. 例如,如果输入如下4 X 4矩阵: 1   2    3     4 5   6    7     8 9   10  11  ...

  7. 剑指offer二十之包含min函数的栈

    一.题目 定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数. 二.思路 用一个栈dataStack保存数据,用另外一个栈minStack保存依次入栈最小的数.每次元素存入minSt ...

  8. 剑指offer六十之按之把二叉树打印成多行

    一.题目 从上到下按层打印二叉树,同一层结点从左至右输出.每一层输出一行.二.思路 队列LinkedList完成层序遍历,用end记录每层结点数目 三.代码 import java.util.Arra ...

  9. 剑指offer五十九之按之字形顺序打印二叉树

    一.题目 请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推.二.思路 详见代码 三.代码 import j ...

随机推荐

  1. 文件锁FileLock

    1.文件锁的定义 FileLock是文件锁,进程锁,用于进程间并发,控制不同程序(JVM)对同一文件的并发访问. FileLock是java 1.4 版本后出现的一个类,它可以通过对一个可写文件(w) ...

  2. Missing artifact net.sf.json-lib:json-lib:jar:2.4错误和Eclipse安装Maven插件错误

    微信公众号:compassblog 欢迎关注.转发,互相学习,共同进步! 有任何问题,请后台留言联系! 1.配置Maven项目的pom.xml文件报错 (1).错误描述:Missing artifac ...

  3. JAVAEE——BOS物流项目03:学习计划、messager、menubutton、登陆拦截器、信息校验和取派员添加功能

    1 学习计划 1.jQuery easyUI messager使用方式 n alert方法 n confirm方法 n show方法 2.jQuery easyUI menubutton使用方式 3. ...

  4. 小甲鱼OD学习第9讲

    这次我们的任务是破解这个要注册的软件,如下图所示 当我们输入账号密码的时候,它会提示输入的账号密码是无效的,如下图 我们把程序载入OD,然后在查找字符串那里输入提示的无效账号密码的字符串,如下图 然后 ...

  5. IDA学习笔记 函数调用约定

    stdcall和cdecl: stdcall和cdecl 压栈方向都是从右到左 区别在于c约定是调用方在函数返回后add esp,n指令清除堆栈中的参数,而stdcall在被调函数内使用ret n来清 ...

  6. bzoj[1835][ZJOI2010]base 基地选址

    bzoj[1835][ZJOI2010]base 基地选址 标签: 线段树 DP 题目链接 题解 这个暴力DP的话应该很容易看出来. dp[i][j]表示造了i个通讯站,并且j是第i个的最小费用. \ ...

  7. 深入分析Java ClassLoader的原理(转)

    一.什么是ClassLoader? 大家都知道,当我们写好一个Java程序之后,不是管是CS还是BS应用,都是由若干个.class文件组织而成的一个完整的Java应用程序,当程序在运行时,即会调用该程 ...

  8. Java经典编程题50道之十三

    一个整数,它加上100后是一个完全平方数,再加上168又是一个完全平方数,请问该数是多少? public class Example13 {    public static void main(St ...

  9. springmvc+mybatis+mysql 数据库插入中文是乱码

    java web项目,前台页面的表单数据,插入到数据库时,结果出现乱码"???"的问题,断断续续折腾了一天时间,废话不说,步骤如下: 一:在web.xml中配置:编码格式拦截器 & ...

  10. shiro进行散列算法操作

    shiro最闪亮的四大特征:认证,权限,加密,会话管理 为了提高应用系统的安全性,这里主要关注shiro提供的密码服务模块: 1.加密工具类的熟悉 首先来个结构图,看看shiro提供了哪些加密工具类: ...