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. 洛谷 [P2764]最小路径覆盖问题

    二分图应用模版 #include <iostream> #include <cstdio> #include <algorithm> #include <cs ...

  2. ORM规约变更经典案例---mysql军规

    先介绍一下<MySQL数据库开发的三十六条军规>,这里只介绍核心的,具体内容大家可以自行百度,这是从底层开发人员到管理者必须知道规范.出自58赶集. 写在前面的话: 总是在灾难发生后,才想 ...

  3. python重新利用shodan API

    前言: 之前写过一个shodan的API调用 感觉写的不这么好.然后现在重新写一个 shodan介绍: shodan是互联网上最可怕的搜索引擎. CNNMoney的一篇文章写道,虽然目前人们都认为谷歌 ...

  4. MySQL数据库基础

    MySQL数据库基础 本文的所有操作是基于CMD环境,MySQL通过在命令行中输入SQL语句对数据库进行操作.配置问题可参考<打通MySQL的操作权限>中的内容,该文算是针对前期的环境配置 ...

  5. Mac下安装php5.6/7.1

    安装环境 OS X EI Capitan 10.11.4 Homebrew安装 homebrew是一个类似于ubuntu中apt-get的一个软件管理器,安装比较简单,在命令行中输入如下代码: rub ...

  6. Django——ContentType及ContentType-signals的使用

    一.ContentType 在django中,有一个记录了项目中所有model元数据的表,就是ContentType,表中一条记录对应着一个存在的model,所以可以通过一个ContentType表的 ...

  7. Android app性能测试小结(7个性能指标)

    1.性能测试的几个指标:       2.性能测试环境准备: 3.启动时间 3.1,监控值的获取方法 启动分为冷启动和热启动,冷启动:应用程序首次启动,进程首次创建并加载资源的过程:热启动:应用程序启 ...

  8. POJ - 2253 Frogger 单源最短路

    题意:给定n个点的坐标,问从第一个点到第二个点的最小跳跃范围.d(i)表示从第一个点到达第i个点的最小跳跃范围. AC代码 #include <cstdio> #include <c ...

  9. 编码问题 php字符编码转换类

    各种平台和软件打开显示的编码问题,需要使用不同的编码,根据我们不同的需求. php 字符编码转换类,支持ANSI.Unicode.Unicode big endian.UTF-8.UTF-8+Bom ...

  10. Luogu P1522 牛的旅行 Cow Tours

    题目描述 农民 John的农场里有很多牧区.有的路径连接一些特定的牧区.一片所有连通的牧区称为一个牧场.但是就目前而言,你能看到至少有两个牧区通过任何路径都不连通.这样,Farmer John就有多个 ...