剑指offer

《剑指offer》第五十六题I:数组中只出现一次的两个数字

ε祈祈猫儿з 提交于 2020-04-08 11:44:44
// 面试题56(一):数组中只出现一次的两个数字 // 题目:一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序 // 找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。 #include <cstdio> unsigned int FindFirstBitIs1(int num); bool IsBit1(int num, unsigned int indexBit); void FindNumsAppearOnce(int data[], int length, int* num1, int* num2) { if (data == nullptr || length < 2) return; int resultExclusiveOR = 0; for (int i = 0; i < length; ++i) //自反性, A XOR B XOR B = A XOR 0 = A resultExclusiveOR ^= data[i]; //因为有两个不同的数, 因此其结果二进制中必定有一位为1 //其中一个数字此位为1, 另一个必定为0. 1 XOR 0 = 1 unsigned int indexOf1 = FindFirstBitIs1(resultExclusiveOR); *num1 = *num2 = 0; for

《剑指offer》第五十题I:字符串中第一个只出现一次的字符

和自甴很熟 提交于 2020-04-05 18:04:09
// 面试题50(一):字符串中第一个只出现一次的字符 // 题目:在字符串中找出第一个只出现一次的字符。如输入"abaccdeff",则输出 // 'b'。 #include <cstdio> #include <string> char FirstNotRepeatingChar(const char* pString) { if (pString == nullptr) return '\0'; const int tableSize = 256; //char为8位, 2 ^ 8 = 256种可能 unsigned int hashTable[tableSize]; //构建哈希表 for (unsigned int i = 0; i < tableSize; ++i) hashTable[i] = 0; const char* pHashKey = pString; //字符串索引/哈希表key值 //第一次遍历统计字符出现次数 while (*(pHashKey) != '\0') hashTable[*(pHashKey++)] ++; //将 ++pHasKey 结合到一句 pHashKey = pString; //第二次遍历寻找出现次数为1的第一个字符 while (*pHashKey != '\0') { if (hashTable[*pHashKey] ==

《剑指offer》—— 10 斐波那契数列

血红的双手。 提交于 2020-03-09 09:51:26
题目: 求斐波那契数列的第n项。 解法一:递归,效率低 public class Fibonacci { public long fibonacci ( int n ) { if ( n <= 0 ) { return 0 ; } if ( n == 1 ) { return 1 ; } return fibonacci ( n - 1 ) + fibonacci ( n - 2 ) ; } } 递归函数的实质是函数调用函数本身,而每一次函数的调用都要在内存中分配空间以保存进行参数,返回地址等。而且往栈里弹出数据,插入数据是需要时间的。最重要的是,多层的递归可能造成调用栈溢出。 很多数字都被重复计算。例如计算10要计算9和8,计算9要计算8和7,此时8便被计算了两次。 解法二: 想办法避免重复计算,从下往上计算,现根据,然后根据f(1)和f(2)计算f(3)… 不能使用数组,无法预先分配数组长度。 public class Fibonacci { private static long fibonacci ( int n ) { if ( n <= 0 ) { return 0 ; } if ( n == 1 ) { return 1 ; } long fiboOne = 1 ; long fiboTwo = 0 ; long fn = 0 ; for ( int i = 2 ;

《剑指offer》和为S的两个数字

萝らか妹 提交于 2020-03-04 15:13:27
本题来自《剑指offer》 和为S的两个数字 题目:   输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。 思路:   头尾双向夹逼遍历,题目是递增排序的数组,当和大于当前值是,那么就向前遍历,如果小于那么就向后遍历。   要求是乘积最小,理论讲,两数相距最远,其乘积最小。 Python Code: # -*- coding:utf-8 -*- class Solution: def FindNumbersWithSum(self, array, tsum): # write code here result = [] #result cache,empty if not isinstance(array, list): #boundart condition judgement return result behind = 0 #first index of array ahead = len(array)-1 #last index of array while behind<ahead: #the condition is behind small ahead cursum = array[behind]+array[ahead] #summation if cursum==tsum: #if

《剑指Offer》Java刷题 NO.8 跳台阶&NO.9 变态跳台阶

混江龙づ霸主 提交于 2020-02-13 17:40:47
《剑指Offer》Java刷题 NO.8 跳台阶&NO.9 变态跳台阶 传送门:《剑指Offer刷题总目录》 时间2020-02-11 题目: 一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。 思路: 其实就是第七题斐波那契数列的一个应用,只不过初始值f(1)=1;f(2)=2; 青蛙跳上第n级台阶只有两种方式,从第n-1级向上跳一级,或者从第n-2级向上跳2级,所以青蛙跳上第n级台阶的方法数就等于这两种方式的方法之和: f(n)=f(n-1)+f(n-2) 拓展升级: 一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。 参考上述思路: 此时青蛙跳上第n级台阶的方法数: f(n)=f(n-1)+f(n-2)+f(n-3)+···+f(2)+f(1)+1[1是直接一次跳到n级] f(n-1)=f(n-2)+f(n-3)+f(n-4)+···+f(2)+f(1)+1,可得: f(n)=2*f(n-1),所以这是一个等比数列, 可得f(n)=2^(n-1) Java代码: public class JumpFloor { public int jumpOnFloor ( int n ) { if ( n == 0 ) return 0 ; else if (

《剑指offer》之扑克牌顺子

天大地大妈咪最大 提交于 2020-02-13 17:26:05
前言 接着来刷一道简单的算法题 题目 LL今天心情特别好,因为他去买了一副扑克牌,发现里面居然有2个大王,2个小王(一副牌原本是54张 _ )…他随机从中抽出了5张牌,想测测自己的手气,看看能不能抽到顺子,如果抽到的话,他决定去买体育彩票,嘿嘿!!“红心A,黑桃3,小王,大王,方片5”,“Oh My God!”不是顺子…LL不高兴了,他想了想,决定大\小 王可以看成任何数字,并且A看作1,J为11,Q为12,K为13。上面的5张牌就可以变成“1,2,3,4,5”(大小王分别看作2和4),“So Lucky!”。LL决定去买体育彩票啦。 现在,要求你使用这幅牌模拟上面的过程,然后告诉我们LL的运气如何, 如果牌能组成顺子就输出true,否则就输出false。为了方便起见,你可以认为大小王是0。 分析 就是一个数组,0表示大小王,可以当癞子,其他的最小是1,最大是13,求给出的这个数组能否组成顺子。 我们仔细想想一个正常的顺子,比如6,7,8,9,10. 那最大值和最小值差为4,并且不能重复。所以我们应该得出两个结论。 1,最大值和最小值相差小于等于4,为什么会小于4呢,因为有癞子0导致的。 2.除了癞子0以外,其他的数字不能重复。 所以根据上面的条件我们就可以写出算法了。 求出最小值,最大值。 重复数字怎么判断呢? 先判断是否为0,不为0,将这个数字作为脚标存到另一个数组中

《剑指Offer》61. 扑克牌顺子

▼魔方 西西 提交于 2020-02-09 03:24:33
题目链接 牛客网 题目描述 五张牌,其中大小鬼为癞子,牌面为 0。判断这五张牌是否能组成顺子。 解题思路 import java . util . * ; public class Solution { public boolean isContinuous ( int [ ] nums ) { if ( nums == null || nums . length < 5 ) return false ; int cnt = 0 ; Arrays . sort ( nums ) ; // 统计癞子数量 for ( int i = 0 ; i < nums . length ; i ++ ) if ( nums [ i ] == 0 ) cnt ++ ; // 使用癞子去补全不连续的顺子 for ( int i = cnt ; i < nums . length - 1 ; i ++ ) { if ( nums [ i ] == nums [ i + 1 ] ) return false ; cnt -= nums [ i + 1 ] - nums [ i ] - 1 ; } return cnt >= 0 ; } } 来源: CSDN 作者: Melo丶 链接: https://blog.csdn.net/weixin_38611497/article/details

《剑指Offer》62. 圆圈中最后剩下的数

点点圈 提交于 2020-02-08 20:19:38
题目链接 牛客网 题目描述 让小朋友们围成一个大圈。然后,随机指定一个数 m,让编号为 0 的小朋友开始报数。每次喊到 m-1 的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,从他的下一个小朋友开始,继续 0…m-1 报数 … 这样下去 … 直到剩下最后一个小朋友,可以不用表演。 返回最后小朋友的编号 解题思路 约瑟夫环,圆圈长度为 n 的解可以看成长度为 n-1 的解再加上报数的长度 m。因为是圆圈,所以最后需要对 n 取余。 public class Solution { public int LastRemaining_Solution ( int n , int m ) { if ( n == 0 ) return - 1 ; if ( n == 1 ) return 0 ; return ( LastRemaining_Solution ( n - 1 , m ) + m ) % n ; } } 来源: CSDN 作者: Melo丶 链接: https://blog.csdn.net/weixin_38611497/article/details/104225241

《剑指Offer》53. 数字在排序数组中出现的次数

霸气de小男生 提交于 2020-02-07 23:34:23
题目链接 牛客网 题目描述 统计一个数字在排序数组中出现的次数。 Input: nums = 1, 2, 3, 3, 3, 3, 4, 6 K = 3 Output: 4 解题思路 排序数组记住二分查找 public class Solution { public int GetNumberOfK ( int [ ] array , int k ) { if ( array == null || array . length == 0 ) return 0 ; int first = binarySearch ( array , k ) ; int last = binarySearch ( array , k + 1 ) ; if ( first == array . length || array [ first ] != k ) return 0 ; else return last - first ; } // 找到>=target的元素最先出现的位置 private int binarySearch ( int [ ] array , int target ) { int l = 0 , h = array . length ; // 注意这里h取到array.length,可以减少一次对last的判断 while ( l < h ) { int m = l + ( h

《剑指Offer》46. 把数字翻译成字符串

你说的曾经没有我的故事 提交于 2020-02-06 18:02:58
题目链接 Leetcode 题目描述 给定一个数字,按照如下规则翻译成字符串:1 翻译成“a”,2 翻译成“b”… 26 翻译成“z”。一个数字有多种翻译可能,例如 12258 一共有 5 种,分别是 abbeh,lbeh,aveh,abyh,lyh。实现一个函数,用来计算一个数字有多少种不同的翻译方法。 解题思路 动态规划,dp[i]表示到第i个字符为止的str有多少中可能 class Solution { public int numDecodings ( String s ) { if ( s == null || s . length ( ) == 0 ) return 0 ; int n = s . length ( ) ; int [ ] dp = new int [ n + 1 ] ; dp [ 0 ] = 1 ; dp [ 1 ] = s . charAt ( 0 ) == '0' ? 0 : 1 ; for ( int i = 2 ; i <= n ; i ++ ) { int one = Integer . valueOf ( s . substring ( i - 1 , i ) ) ; if ( one != 0 ) dp [ i ] += dp [ i - 1 ] ; int two = Integer . valueOf ( s . substring