文章目录

  • 目录
    • 第31 题:
      • 解题思路:
      • 代码实现:
        • c++
        • python
    • 第32题:
      • 解题思路:
      • 代码实现:
        • c++
        • python
    • 第33题:
      • 解题思路:
      • 代码实现:
        • c++
        • python
    • 第34题:
      • 解题思路:
      • 代码实现:
        • c++
        • python
    • 第35题:
      • 解题思路:
      • 代码实现:
        • c++
        • python
    • 第36题:
      • 解题思路:
      • 代码实现:
        • c++
        • python
    • 第37题:
      • 解题思路:
      • 代码实现:
        • c++
        • python
    • 第38题:
      • 解题思路:
      • 代码实现:
        • c++
          • 递归实现
        • python
    • 第39题:
      • 解题思路:
      • 代码实现:
        • c++
        • python
    • 第40题:
      • 解题思路:
      • 代码实现:
        • c++
        • python

目录

第31 题:

输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。

解题思路:

代码实现:

c++

class Solution {public://比较两个字符串大小的函数,返回较小的那个字符串static bool cmp(int a,int b){string A="";string B="";A+=to_string(a);A+=to_string(b);B+=to_string(b);B+=to_string(a);return A<B;}//输出最小的排序string PrintMinNumber(vector<int> numbers) {string  answer="";sort(numbers.begin(),numbers.end(),cmp);//降序排序for(int i=0;i<numbers.size();i++){answer+=to_string(numbers[i]);}return answer;}};

运行时间:2ms

占用内存:480k

python

# -*- coding:utf-8 -*-

第32题:

把只包含质因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含质因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。

解题思路:

  • 个人想法:我们首先要定义一个判别一个数是否为丑数的函数,而要判别一个数是否为丑数则只需要看其质数因子是否都是2,3,5,如果有其他的肯定不是丑数。在定义好丑数的识别函数后,就可以定义一个函数输出第N个丑数。
  • 别人的想法:
    通俗易懂的解释:
    首先从丑数的定义我们知道,一个丑数的因子只有2,3,5,那么丑数p = 2 ^ x * 3 ^ y * 5 ^ z,换句话说一个丑数一定由另一个丑数乘以2或者乘以3或者乘以5得到,那么我们从1开始乘以2,3,5,就得到2,3,5三个丑数,在从这三个丑数出发乘以2,3,5就得到4,6,10,6,9,15,10,15,25九个丑数,我们发现这种方法会得到重复的丑数,而且我们题目要求第N个丑数,这样的方法得到的丑数也是无序的。那么我们可以维护三个队列:
    (1)丑数数组: 1
    乘以2的队列:2
    乘以3的队列:3
    乘以5的队列:5
    选择三个队列头最小的数2加入丑数数组,同时将该最小的数乘以2,3,5放入三个队列;
    (2)丑数数组:1,2
    乘以2的队列:4
    乘以3的队列:3,6
    乘以5的队列:5,10
    选择三个队列头最小的数3加入丑数数组,同时将该最小的数乘以2,3,5放入三个队列;
    (3)丑数数组:1,2,3
    乘以2的队列:4,6
    乘以3的队列:6,9
    乘以5的队列:5,10,15
    选择三个队列头里最小的数4加入丑数数组,同时将该最小的数乘以2,3,5放入三个队列;
    (4)丑数数组:1,2,3,4
    乘以2的队列:6,8
    乘以3的队列:6,9,12
    乘以5的队列:5,10,15,20
    选择三个队列头里最小的数5加入丑数数组,同时将该最小的数乘以2,3,5放入三个队列;
    (5)丑数数组:1,2,3,4,5
    乘以2的队列:6,8,10,
    乘以3的队列:6,9,12,15
    乘以5的队列:10,15,20,25
    选择三个队列头里最小的数6加入丑数数组,但我们发现,有两个队列头都为6,所以我们弹出两个队列头,同时将12,18,30放入三个队列;
    ……………………
    疑问:
    1.为什么分三个队列?
    丑数数组里的数一定是有序的,因为我们是从丑数数组里的数乘以2,3,5选出的最小数,一定比以前未乘以2,3,5大,同时对于三个队列内部,按先后顺序乘以2,3,5分别放入,所以同一个队列内部也是有序的;
    2.为什么比较三个队列头部最小的数放入丑数数组?
    因为三个队列是有序的,所以取出三个头中最小的,等同于找到了三个队列所有数中最小的。
    实现思路:
    我们没有必要维护三个队列,只需要记录三个指针显示到达哪一步;“|”表示指针,arr表示丑数数组;
    (1)1
    |2
    |3
    |5
    目前指针指向0,0,0,队列头arr[0] * 2 = 2, arr[0] * 3 = 3, arr[0] * 5 = 5
    (2)1 2
    2 |4
    |3 6
    |5 10
    目前指针指向1,0,0,队列头arr[1] * 2 = 4, arr[0] * 3 = 3, arr[0] * 5 = 5
    (3)1 2 3
    2| 4 6
    3 |6 9
    |5 10 15
    目前指针指向1,1,0,队列头arr[1] * 2 = 4, arr[1] * 3 = 6, arr[0] * 5 = 5

代码实现:

c++

class Solution {public:int GetUglyNumber_Solution(int index) {if (index < 7)return index;vector<int> res(index);res[0] = 1;int t2 = 0, t3 = 0, t5 = 0, i;for (i = 1; i < index; ++i){res[i] = min(res[t2] * 2, min(res[t3] * 3, res[t5] * 5));if (res[i] == res[t2] * 2)t2++;if (res[i] == res[t3] * 3)t3++;if (res[i] == res[t5] * 5)t5++;}return res[index - 1];}
};

运行时间:3ms

占用内存:504k

python

# -*- coding:utf-8 -*-

第33题:

在一个字符串(0<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1(需要区分大小写).

解题思路:

  • 使用字典结构存储字母和字母出现的次数,然后遍历该字典,输出只出现一次的字母的第一个便是我们需要的答案

代码实现:

c++

class Solution {public:int FirstNotRepeatingChar(string str) {map<char, int> mp;for(int i = 0; i < str.size(); ++i)mp[str[i]]++;for(int i = 0; i < str.size(); ++i){if(mp[str[i]]==1)return i;}return -1;}
};

运行时间:4ms

占用内存:476k

python

由于Python中的字典是keys是无序的所以不好用于实现

# -*- coding:utf-8 -*-

第34题:

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

解题思路:

代码实现:

c++


python

# -*- coding:utf-8 -*-

第35题:

输入两个链表,找出它们的第一个公共结点。

解题思路:

  • 初步想法:

    • 暴力解法:通过2层for循环遍历两个链表,然后找到第一个公共节点,然后打印出来。

公共结点的意思是两个链表相遇之后后面都是一样的,我还以为是交叉的两个链表

代码实现:

c++

class Solution {public:ListNode* FindFirstCommonNode( ListNode *pHead1, ListNode *pHead2) {int len1 = findListLenth(pHead1);int len2 = findListLenth(pHead2);if(len1 > len2){pHead1 = walkStep(pHead1,len1 - len2);  //如果链表1比较长,则让链表1将差值走掉}else{pHead2 = walkStep(pHead2,len2 - len1);}while(pHead1 != NULL){if(pHead1 == pHead2) return pHead1;  //如果找到了相同的节点,则返回pHead1 = pHead1->next;pHead2 = pHead2->next;}return NULL;}int findListLenth(ListNode *pHead1){if(pHead1 == NULL) return 0;int sum = 1;while(pHead1 = pHead1->next) sum++;return sum;}//让链表遍历走step步ListNode* walkStep(ListNode *pHead1, int step){while(step--){pHead1 = pHead1->next;}return pHead1;}
};

运行时间:3ms

占用内存:376k

python

# -*- coding:utf-8 -*-
class Solution:def getListLen(self,pHead):if pHead == None:return 0dataLen = 0while pHead != None:dataLen += 1pHead = pHead.nextreturn dataLendef FindFirstCommonNode(self, pHead1, pHead2):# write code heredataLen1 = self.getListLen(pHead1)dataLen2 = self.getListLen(pHead2)if dataLen1 > dataLen2:tempStep = dataLen1 - dataLen2while tempStep:pHead1 = pHead1.nexttempStep -= 1else:tempStep = dataLen2 - dataLen1while tempStep:pHead2 = pHead2.nexttempStep -= 1while pHead1!= None:if pHead1==pHead2:return pHead1pHead1 = pHead1.nextpHead2 = pHead2.next

运行时间:30ms

占用内存:5720k

第36题:

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

解题思路:

  • 从题目中,我们可以看到是对一个排序数据的查找问题,但是又和纯粹的查找问题不同,我们可以使用二分查找的方法,但是㤇改进,因为题目中是找某个数字出现的次数,只要找到了这个数字,向前,向后遍历便可以统计出数字的出现次数。

代码实现:

c++

class Solution {public:int GetNumberOfK(vector<int> data ,int k) {if(data.size() <= 0){return 0;}int start = 0;int end = data.size() - 1;int dataIndex = -1;  //保存查找该数的位置//使用二分查找对该数进行查找while(start <= end){int mid = (start + end) * 0.5;if(k == data[mid]){dataIndex = mid;break;}else if(k > data[mid]){start = mid + 1;}else{end = mid - 1;}}//如果没有找到该数,直接返回0if(dataIndex == -1){return 0;}//向左边进行查找int dataCount = 1;int tempIndex = dataIndex - 1;while(tempIndex >= 0){if(data[tempIndex] != k){break;}tempIndex--;dataCount++;}//向右边进行查找tempIndex = dataIndex + 1;while(tempIndex < data.size()){if(data[tempIndex] != k){break;}tempIndex++;dataCount++;}return dataCount;}
};

运行时间:4ms

占用内存:376k

python

# -*- coding:utf-8 -*-
class Solution:def GetNumberOfK(self, data, k):# write code hereif len(data) <= 0:return 0tempDict = {}for i in data:if i not in tempDict.keys():tempDict[i] = 1else:tempDict[i] += 1if k not in tempDict.keys():return 0else:return tempDict[k]

运行时间:29ms

占用内存:5680k

第37题:

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

解题思路:

  • 初步思想:这是一个树的前序遍历的算法题,我们只需要广度优先遍历该树,然后用一个数组记录下每次运行到叶子节点的路径长度,最后将路径进行排序即可,取出路径最长的那个即可。

代码实现:

c++

class Solution {public:int TreeDepth(TreeNode* pRoot){if (!pRoot) return 0;queue<TreeNode*> que;que.push(pRoot);int depth=0;while (!que.empty()) {int size=que.size();depth++;for (int i=0;i<size;i++) {      //一次处理一层的数据TreeNode *node=que.front();que.pop();if (node->left) que.push(node->left);if (node->right) que.push(node->right);}}return depth;}
};

运行时间:3ms

占用内存:372k

递归版本

#include <algorithm>
class Solution {public:int TreeDepth(TreeNode* pRoot){if (!pRoot) return 0;return max(1+TreeDepth(pRoot->left) , 1+TreeDepth(pRoot->right));}
};

运行时间:3ms

占用内存:460k

python

递归版本

# -*- coding:utf-8 -*-
class Solution:def TreeDepth(self, pRoot):# write code hereif pRoot == None:return 0return max(self.TreeDepth(pRoot.left) + 1,self.TreeDepth(pRoot.right) + 1)

运行时间:23ms

占用内存:5752k

第38题:

输入一棵二叉树,判断该二叉树是否是平衡二叉树。

解题思路:

  • 初步思想:根据平衡二叉树的性质,即每一棵树的左右子树高度差必须在1之内,所以可以转换为一个查看每个子树的其左右子树的深度问题,如果深度的差在1以内,则为平衡二叉树。可以使用递归的做法!

代码实现:

c++

递归实现
#include <algorithm>
class Solution {public://返回树的最大的深度int treeMaxDepth(TreeNode* root){if(root==NULL) return 0;return 1 + max(treeMaxDepth(root->left),treeMaxDepth(root->right));}bool IsBalanced_Solution(TreeNode* pRoot) {if(pRoot==NULL) return true; return abs(treeMaxDepth(pRoot->left) - treeMaxDepth(pRoot->right)) <= 1 && IsBalanced_Solution(pRoot->right) && IsBalanced_Solution(pRoot->left);}
};

运行时间:11ms

占用内存:616k

python

# -*- coding:utf-8 -*-
class Solution:def treeMaxDepath(self , pRoot):if pRoot == None:return 0return 1 + max(self.treeMaxDepath(pRoot.left) ,self.treeMaxDepath(pRoot.right) )def IsBalanced_Solution(self, pRoot):# write code hereif pRoot == None:return Truereturn abs(self.treeMaxDepath(pRoot.left) - self.treeMaxDepath(pRoot.right)) <=1 and self.IsBalanced_Solution(pRoot.left) and self.IsBalanced_Solution(pRoot.right)

运行时间:36ms

占用内存:5672k

第39题:

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

解题思路:

  • 初步的思路:使用hash map对数字出现的频率进行统计,遍历完数组也就统计完成,然后找出hash map中出现次数为1的两个数即可。

代码实现:

c++

class Solution {public:void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) {if(data.size()<2)return ;int size=data.size();int temp=data[0];for(int i=1;i<size;i++)temp=temp^data[i];if(temp==0)return ;int index=0;while((temp&1)==0){temp=temp>>1;++index;}*num1=*num2=0;for(int i=0;i<size;i++){if(IsBit(data[i],index))*num1^=data[i];else*num2^=data[i];}}bool IsBit(int num,int index){num=num>>index;return (num&1);}
};

运行时间:3ms

占用内存:488k

python

# -*- coding:utf-8 -*-
class Solution:# 返回[a,b] 其中ab是出现一次的两个数字def FindNumsAppearOnce(self, array):# write code heretempDict = {}resultList = []for i in array:if i in tempDict.keys():tempDict[i] += 1else:tempDict[i] = 1for keys , values in tempDict.items():if values == 1:resultList.append(keys)return resultList

运行时间:38ms

占用内存:5856k

第40题:

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

解题思路:

  • 暴力法:时间复杂度为O(N^2)。分别计算以1开头的和为100的递增数列,然后计算以2开头的和为100的递增数列,依次类推。
  • 参考其他人的:
    1)由于我们要找的是和为S的连续正数序列,因此这个序列是个公差为1的等差数列,而这个序列的中间值代表了平均值的大小。假设序列长度为n,那么这个序列的中间值可以通过(S / n)得到,知道序列的中间值和长度,也就不难求出这段序列了。
    2)满足条件的n分两种情况:
    n为奇数时,序列中间的数正好是序列的平均值,所以条件为:(n & 1) == 1 && sum % n == 0;
    n为偶数时,序列中间两个数的平均值是序列的平均值,而这个平均值的小数部分为0.5,所以条件为:(sum % n) * 2 == n.
    3)由题可知n >= 2,那么n的最大值是多少呢?我们完全可以将n从2到S全部遍历一次,但是大部分遍历是不必要的。为了让n尽可能大,我们让序列从1开始,
    根据等差数列的求和公式:S = (1 + n) * n / 2,得到.

最后举一个例子,假设输入sum = 100,我们只需遍历n = 13~2的情况(按题意应从大到小遍历),n = 8时,得到序列[9, 10, 11, 12, 13, 14, 15, 16];n = 5时,得到序列[18, 19, 20, 21, 22]

代码实现:

c++

class Solution {public:vector<vector<int> > FindContinuousSequence(int sum) {vector<vector<int>> resArray;vector<int> tempArray;int tempSum , j , i;for(i = 1 ; i < sum ; i++){tempSum = i;tempArray.clear();tempArray.push_back(i);for(j = i+1 ; j < sum ; j++){tempSum += j;tempArray.push_back(j);if(tempSum == sum){resArray.push_back(tempArray);break;} }}return resArray; }
};

运行时间:3ms

占用内存:484k

python

# -*- coding:utf-8 -*-
class Solution:def FindContinuousSequence(self, tsum):# write code hereresultList = []for i in range(1,tsum):tempSum = itempList = [i]for j in range(i+1,tsum):tempSum += jtempList.append(j)if tempSum == tsum:resultList.append(tempList)breakreturn resultList

运行时间:25ms

占用内存:5852k

剑指offer(刷题31-40)--c++,Python版本相关推荐

  1. 剑指offer(刷题51-60)--c++,Python版本

    文章目录 目录 第51题: 解题思路: 代码实现: c++ python 第52题: 解题思路: 代码实现: c++ python 第53题: 解题思路: 代码实现: c++ python 第54题: ...

  2. 剑指offer(刷题61-65)--c++,Python版本

    文章目录 目录 第61题: 解题思路: 代码实现: c++ python 第62题: 解题思路: 代码实现: c++ python 第63题: 解题思路: 代码实现: c++ python 第64题: ...

  3. 剑指offer(刷题41-50)--c++,Python版本

    文章目录 目录 第41题: 解题思路: 代码实现: c++ python 第42题: 解题思路: 代码实现: c++ python 第43题: 解题思路: 代码实现: c++ python 第44题: ...

  4. 剑指offer(刷题21-30)--c++,Python版本

    文章目录 目录 第 21题: 解题思路: 代码实现: c++ python 第22 题: 解题思路: 代码实现: c++ python 第23 题: 解题思路: 代码实现: c++ python 第2 ...

  5. 原 剑指offer(刷题11-20)--c++,Python版本

    文章目录 目录 第11题: 解题思路: 代码实现: c++ python 第12题: 解题思路: 代码实现: c++ python 第13 题: 解题思路: 代码实现: c++ python 第 14 ...

  6. 剑指offer(刷题1-10)--c++,Python版本

    文章目录 目录 第一题: 解题思路: 代码实现: c++ 顺序查找 二分查找 Python 第二题: 解题思路: 代码实现: c++ python 第三题: 解题思路: 代码实现: c++ 使用栈辅助 ...

  7. 剑指offer刷题记录 python3 Java

    剑指offer刷题记录 python3 Java 剑指 Offer 09. 用两个栈实现队列 剑指 Offer 10- I. 斐波那契数列 剑指 Offer 03. 数组中重复的数字 [★]剑指 Of ...

  8. 【LeetCode 剑指offer刷题】树题6:28 对称二叉树(101. Symmetric Tree)

    [LeetCode & 剑指offer 刷题笔记]目录(持续更新中...) 101. Symmetric Tree /**  * Definition for a binary tree no ...

  9. 【LeetCode 剑指offer刷题】数组题2:57 有序数组中和为s的两个数(167 Two Sum II - Input array is sorted)...

    [LeetCode & 剑指offer 刷题笔记]目录(持续更新中...) 57 有序数组中和为s的两个数 题目描述 输入一个递增排序的数组和一个数字S,在数组中查找两个数,是的他们的和正好是 ...

最新文章

  1. 2.Spring Cloud Alibaba教程:Linux安装Nacos1.3.1以及配置MySQL持久化
  2. c 和 java 差异_java和C/C++的差异是什么
  3. Android调用手机浏览器打开某网页出现异常情况
  4. [ js处理表单 ]:动态赋值
  5. apple ii 模拟器 mac_苹果自研芯片Mac价格曝光
  6. confluence启动不起来_汽车“一键启动”只用来点火?太浪费!你不知道的还有这3个功能...
  7. 谁更安全?WI-FI无线网加密方式大比拼
  8. 选择WebSockets还是REST?
  9. .net通用权限框架B/S (五)--WEB(1)首页
  10. 反转链表与分组反转链表
  11. RFID天线接头分类
  12. 栅栏密码解密——Java实现
  13. 防止linux子系统关闭,Linux关闭selinux安全子系统的方法
  14. 分库分表中间件Sharding-JDBC详解
  15. 计算机硬盘图标闪烁,电脑本地磁盘图标显示异常如何解决
  16. java中Scanner,Randon,ArrayList
  17. linux打包文件夹命令
  18. python股票数据分析实例_Python之简单股票数据分析
  19. sqlserver2005 sql server database services安装失败解决方法
  20. Outlook Express常见问答

热门文章

  1. php怎么调试小程序,教你如何配置微信小程序
  2. python中for和while可以有else_Python 中的for,if-else和while语句
  3. java 类型转换_java中的基本数据类型的转换
  4. 神经网络与深度学习——TensorFlow2.0实战(笔记)(四)(python函数)
  5. 通过VisualSVN的POST-COMMIT钩子自动部署代码
  6. 【转】CT球管小知识--热容量
  7. 【转】1.8异步编程:.NET 4.5 基于任务的异步编程模型(TAP)
  8. gibmacos 网络加速_黑苹果教程续集,利用EFI在线安装MacOS
  9. 光学字符识别 Tesseract-OCR 的下载、安装和基本用法
  10. 【Loj - 515】贪心只能过样例(暴力,或01背包 + bitset)