《剑指offer》算法题第一天
按照个人计划,从今天开始做《剑指offer》上面的算法题,练习平台为牛客网,上面对每道题都有充分的测试实例,感觉还是很不错的。今天下午做了四道题,分别为:
1. 二叉树的深度(书55题)
二叉树的深度
判断平衡二叉树
2. 数组中数字出现的次数(书56题)
数组中只出现一次的两个数字
3. 和为S的数字(书57题)
和为S的连续正数序列
和为S的两个数字
4. 翻转字符串(书58题)
左旋转字符串
翻转单词顺序列
二叉树类型的问题在leetcode上多次遇到,剑指上的题也比较简单,这边就不再说明,只在最后贴出代码,需要注意的是判断平衡二叉树如何使用一次遍历来判断(利用后序遍历,从叶节点往上判断)。
和为S的数字利用的是Two Pointers的思想,也算比较容易,所以今天的重点是第2,4题。
2. 数组中数字出现的次数
题目描述:一个整型数组里除两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。
本题采用位运算,与leetcode上137. Single Number II类似,且在Discuss中有大神贴出了解法和数学解释,感兴趣的同学可以了解一下。与leetcode上不同的是,本题有两个数字只出现一次,因此较为麻烦。
思路: 如果能把原数组分为两个只有一个数字出现的子数组,就能够用异或运算得出这两个数。 从头到尾异或数组中的每个数字,最终得到两个只出现一次的数字的异或结果。 由于这两个数字不一样,异或的结果肯定不为0,也就是说这个结果数字的二进制表示中至少有一位为1。 在结果数字中找到第一个为1的位的位置,记为第n位,以第n位是不是1为标准把原数组中的数字分成两个子数组,第一个子数组中每个数字的第n位都是1,而第二个子数组中每个数字的第n位都是0。这样,就把原数组分为了两个子数组,在每个子数组中只有一个数出现一次,其他数字都出现了两次。
实现代码:
//num1,num2分别为长度为1的数组。传出参数
//将num1[0],num2[0]设置为返回结果
public class Solution {
public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
int t = 0; //第一轮异或的结果
for(int n:array){
t ^= n;
}
int firstOne = FindFirstOne(t);//找到第一位1的位置
num1[0] = 0;
num2[0] = 0;
for(int n:array){
if(IsBit1(n,firstOne)){//根据第n位是否为1将数组分开
num1[0] ^= n;
}else{
num2[0] ^= n;
}
}
} public int FindFirstOne(int t){
int first = 0;
while((t & 1) == 0 && first < 32){//int型为32位
t = t>>1;
first++;
}
return first;
} public boolean IsBit1(int num,int indexBit){
num = num >> indexBit;
return (num & 1) == 1;
}
}
4. 翻转字符串
题目描述: 翻转单词顺序: 输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。 为简单起见,标点符号和普通字母一样处理。如“I am a student.”,则输出为"student. a am I"。 左旋转字符串: 把字符串前面的若干个字符转移到字符串的尾部。 如输入"abcdefg"和数字2,则输出“cdefgab”。
这题考察的如何灵活的运用字符串翻转来处理新的问题,下面给出字符串翻转的实现代码,代码中,字符串首先被转化为字符数组再进行操作。
public void ReverseString(char[] array,int start,int end){
if(start >= end)
return;
while(start < end){
char tmp = array[start];
array[start] = array[end];
array[end] = tmp;
start++;
end--;
}
}
思路如下:
翻转单词顺序: 首先将句子中的所有字符翻转,如"I am a student."翻转得到".tneduts a ma I" 再将句子内的单词翻转回来得到"student. a am I" 左旋转字符串:
以"abcdefg"为例,把字符串根据n分为两部分
先对每一部分分别翻转,得到"bagfedc" 然后再对整个字符串进行翻转,得到"cdefgab"
代码如下:
翻转单词顺序:
public String ReverseSentence(String str) {
char[] array = str.toCharArray();
ReverseString(array,0,array.length-1);
int s = 0;
for(int end = 0; end < array.length; end++){
if(array[end] == ' '){
ReverseString(array,s,end-1);
s = end+1;
}
}
ReverseString(array,s,array.length-1);
return String.valueOf(array);
}
左旋转字符串:
public String LeftRotateString(String str,int n) {
int len = str.length();
if(len <= 1 || n%len == 0) return str;
n %= len;
char[] array = str.toCharArray();
ReverseString(array,0,n-1);
ReverseString(array,n,len-1);
ReverseString(array,0,len-1);
return String.valueOf(array);
}
最后贴上第1和第3题的代码:
二叉树:
//二叉树的深度
public class Solution {
public int TreeDepth(TreeNode root) {
if(root == null)
return 0;
int left = TreeDepth(root.left);
int right = TreeDepth(root.right);
return Math.max(left,right)+1;
}
} //判断平衡二叉树
public class Solution {
public boolean IsBalanced_Solution(TreeNode root) {
if(root == null)
return true;
return maxDepth(root) != -1;
} public int maxDepth(TreeNode node){
if(node == null)
return 0;
int left = maxDepth(node.left);
int right = maxDepth(node.right);
if(left == -1 || right == -1 || Math.abs(left-right) > 1){
return -1;
}
return Math.max(left,right)+1;
}
}
和为S的数字:
//和为S的两个数字
import java.util.ArrayList;
public class Solution {
public ArrayList<Integer> FindNumbersWithSum(int [] array,int sum) {
ArrayList<Integer> res = new ArrayList();
if(array.length == 0) return res;
int head = 0, tail = array.length-1;
while(head < tail){
int p = array[head];
int q = array[tail];
if(p+q == sum){
res.add(p);
res.add(q);
break;
}else if(p+q > sum){
tail --;
}else{
head ++;
}
}
return res;
}
} //和为S的连续正数序列
import java.util.ArrayList;
public class Solution {
public ArrayList<ArrayList<Integer> > FindContinuousSequence(int sum) {
int small = 1, big = 2, mid = (sum+1)/2;
ArrayList<ArrayList<Integer>> res = new ArrayList();
ArrayList<Integer> tmp = new ArrayList();
tmp.add(small);
tmp.add(big);
int total = small+big;
while(small < mid){
if(total == sum){
res.add(new ArrayList(tmp));
}
if(total > sum){
total -= small;
small++;
tmp.remove(0);
}else{
big++;
total += big;
tmp.add(big);
}
}
return res;
}
}
《剑指offer》算法题第一天的更多相关文章
- 剑指offer算法题
数组中只出现一次的数字(一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字): 解法在于位运算中的异或,直接异或可以得到这两个数的异或,按照最后的有效数字位可以 ...
- 剑指offer算法总结
剑指offer算法学习总结 节选剑指offer比较经典和巧妙的一些题目,以便复习使用.一部分题目给出了完整代码,一部分题目比较简单直接给出思路.但是不保证我说的思路都是正确的,个人对算法也不是特别在行 ...
- 剑指Offer编程题1——二维数组中的查找
剑指Offer编程题1---------------二维数组中的查找 题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完 ...
- 剑指Offer——算法复杂度中的O(logN)底数是多少
剑指Offer--算法复杂度中的O(logN)底数是多少 前言 无论是计算机算法概论.还是数据结构书中,关于算法的时间复杂度很多都用包含O(logN)这样的描述,但是却没有明确说logN的底数究竟是多 ...
- 剑指Offer编程题2——替换空格
剑指Offer编程题2——替换空格 题目描述 请实现一个函数,将一个字符串中的每个空格替换成“%20”.例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happ ...
- 剑指offer编程题66道题 36-66
36.两个链表的第一个公共节点 题目描述 输入两个链表,找出它们的第一个公共结点. 1.具有重合节点的两个链表是一个Y字性,用两个堆栈放这两个链表,从尾部开始遍历,直到遍历到最后一个重合节点. 这种算 ...
- 牛客网剑指offer刷题总结
二维数组中的查找: 题目描述:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 两 ...
- LeetCode剑指Offer刷题总结(一)
LeetCode过程中值得反思的细节 以下题号均指LeetCode剑指offer题库中的题号 本文章将每周定期更新,当内容达到10题左右时将会开下一节. 二维数组越界问题04 public stati ...
- 剑指offer刷题(Tree)
开篇 二刷剑指offer了,本来用Tyora记的笔记,发现字数到四万了就变得好卡o(╥﹏╥)o,刚好开始写博客,就转过来吧,记下来子自己看.不废话,开刷... JZ26. 树的子结构 输入两棵二叉树A ...
- 剑指offer刷题
1.面试题43. 1-n整数中1出现的次数 输入一个整数 n ,求1-n这n个整数的十进制表示中1出现的次数. 例如,输入12,1-12这些整数中包含1 的数字有1.10.11和12,1一共出现了5次 ...
随机推荐
- jquery创建元素并添加到另一个元素中
$('<tr>').data('code', code) .append( // 方法 $('<td>').appen ...
- (5.8)mysql高可用系列——MySQL中的GTID复制(实践篇)
一.基于GTID的异步复制(一主一从)无数据/少数据搭建 二.基于GTID的无损半同步复制(一主一从)(mysql5.7)基于大数据量的初始化 正文: [0]概念 [0.5]GTID 复制(mysql ...
- Clion 常用功能
1.创建新文件并加入项目 打开CMakeList.txt,加入这样的一段话,随后点击图中的Reload changes add_executable(项目名 文件名) 2.文件重命名,移动,复制,移除 ...
- php 内存原理
1.内存结构: 栈区:保存变量名,对CPU,读写速度很快 堆区:保存复杂的数据结构,想对象,数组,复杂的字符串等. 数据段:数据段分为数据段全局区(简单的数据,整型和布尔类型)和数据段静态区(存储静态 ...
- Hive 教程(九)-python with hive
本文介绍用 python 远程连接 hive,此时需要 hive 启动 hiveserver2 服务 windows 下报如下错误 thrift.transport.TTransport.TTrans ...
- JS中的继承(下)
JS中的继承(下) 在上一篇 JS中的继承(上) 我们介绍了3种比较常用的js继承方法,如果你没看过,那么建议你先看一下,因为接下来要写的内容, 是建立在此基础上的.另外本文作为我个人的读书笔记,才疏 ...
- Robot Framework(三)项目实践出现的问题以及解决方法
导航: 1.元素定位失败 2.系统自带的确认弹窗 3.ElementNotVisibleException: Message: element not visible 1.元素定位失败(使用frame ...
- 福建工程学院第十四届ACM校赛J题题解
第六集,想不到你这个浓眉大眼的都叛变革命了 题意: 给你两个只包含01的字符串S和T,问你在允许一次错误的情况下,T是否能成为S的子串 思路: 这个问题的解法挺多,我是用fft匹配的,也比较简单,针对 ...
- python 中的 [:-1] 和 [::-1]
1.案例解释 a='python' b=a[::-1] print(b) #nohtyp c=a[::-2] print(c) #nhy #从后往前数的话,最后一个位置为-1 d=a[:-1] #从位 ...
- HTTPS中CA证书的签发及使用过程
1,HTTPS 简单来讲,HTTPS (Secure Hypertext Transfer Protocol)安全超文本传输协议就是安全的HTTP,我们知道HTTP是运行在TCP层之上的,HTTPS在 ...