当前位置: 代码迷 >> 综合 >> 852. 山脉数组的峰顶索引;162. 寻找峰值;165. 比较版本号;166. 分数到小数;171. Excel表列序号;172. 阶乘后的零
  详细解决方案

852. 山脉数组的峰顶索引;162. 寻找峰值;165. 比较版本号;166. 分数到小数;171. Excel表列序号;172. 阶乘后的零

热度:5   发布时间:2024-02-13 10:32:09.0

我们把符合下列属性的数组 A 称作山脉:


A.length >= 3
存在 0 < i < A.length - 1 使得A[0] < A[1] < ... A[i-1] < A[i] > A[i+1] > ... > A[A.length - 1]


给定一个确定为山脉的数组,返回任何满足 A[0] < A[1] < ... A[i-1] < A[i] > A[i+1] > ... > A[A.length - 1] 的 i 的值。

 

示例 1:

输入:[0,1,0]
输出:1


示例 2:

输入:[0,2,1,0]
输出:1

 

提示:


3 <= A.length <= 10000
0 <= A[i] <= 10^6
A 是如上定义的山脉


class Solution {
public:int peakIndexInMountainArray(vector<int>& A) {int le = 1, ri = A.size() - 2;while (le <= ri) {int mid = le + ((ri - le) >> 1);if (A[mid] > A[mid - 1] && A[mid] > A[mid + 1]) return mid;else if (A[mid] <= A[mid - 1]) ri = mid - 1;else le = mid + 1;}return -1;}
};

峰值元素是指其值大于左右相邻值的元素。

给定一个输入数组 nums,其中 nums[i] ≠ nums[i+1],找到峰值元素并返回其索引。

数组可能包含多个峰值,在这种情况下,返回任何一个峰值所在位置即可。

你可以假设 nums[-1] = nums[n] = -∞。

示例 1:

输入: nums = [1,2,3,1]
输出: 2
解释: 3 是峰值元素,你的函数应该返回其索引 2。

示例 2:

输入: nums = [1,2,1,3,5,6,4]
输出: 1 或 5 
解释: 你的函数可以返回索引 1,其峰值元素为 2;
或者返回索引 5, 其峰值元素为 6。


说明:

你的解法应该是 O(logN) 时间复杂度的。

class Solution {
public:int findPeakElement(vector<int>& nums) {if (nums.size() == 1) return 0;                     // 除此情况外,不可能有mid_le,mid_ri同时越界的情况存在int le = 0, ri = nums.size() - 1, pos = -1;while (le <= ri) {int mid = le + ((ri - le) >> 1);int mid_le = mid - 1, mid_ri = mid + 1;if (mid_le != -1 && mid_ri != nums.size()) {    // 正常情况:顶端/增/减/底端if (nums[mid] > nums[mid_le] && nums[mid] > nums[mid_ri]) {return mid;} else if (nums[mid] < nums[mid_ri]) {le = mid_ri;} else {ri = mid_le;}} else if (mid_le == -1) {                      // mid_le -> mid: 必增情况if (nums[mid] > nums[mid_ri]) return mid;else le = mid_ri;} else {                                        // mid -> mid_ri: 必减情况if (nums[mid] > nums[mid_le]) return mid;else ri = mid_le;}            }return -1;}
};

比较两个版本号 version1 和 version2。
如果 version1 > version2 返回 1,如果 version1 < version2 返回 -1, 除此之外返回 0。

你可以假设版本字符串非空,并且只包含数字和 . 字符。

 . 字符不代表小数点,而是用于分隔数字序列。

例如,2.5 不是“两个半”,也不是“差一半到三”,而是第二版中的第五个小版本。

你可以假设版本号的每一级的默认修订版号为 0。例如,版本号 3.4 的第一级(大版本)和第二级(小版本)修订号分别为 3 和 4。其第三级和第四级修订号均为 0。

示例 1:

输入: version1 = "0.1", version2 = "1.1"
输出: -1

示例 2:

输入: version1 = "1.0.1", version2 = "1"
输出: 1

示例 3:

输入: version1 = "7.5.2.4", version2 = "7.5.3"
输出: -1

示例 4:

输入:version1 = "1.01", version2 = "1.001"
输出:0
解释:忽略前导零,“01” 和 “001” 表示相同的数字 “1”。

示例 5:

输入:version1 = "1.0", version2 = "1.0.0"
输出:0
解释:version1 没有第三级修订号,这意味着它的第三级修订号默认为 “0”。

 

提示:


版本字符串由以点 (.) 分隔的数字字符串组成。这个数字字符串可能有前导零。
版本字符串不以点开始或结束,并且其中不会有两个连续的点。

class Solution {
public:int compareVersion(string version1, string version2) {stringstream ss1(version1), ss2(version2);string s1, s2;while (true) {auto &b1 = getline(ss1, s1, '.');   // 必须引用auto &b2 = getline(ss2, s2, '.');   // 不能是bool, 因为istream& getline (istream&  is, string& str, char delim);if (!b1 && !b2) {return 0;} else if (!b1) {if (stoi(s2)) return -1;} else if (!b2) {if (stoi(s1)) return 1;} else {auto int_s1 = stoi(s1), int_s2 = stoi(s2);if (int_s1 == int_s2) continue;else if (int_s1 > int_s2) return 1;else return -1;}}}
};

给定两个整数,分别表示分数的分子 numerator 和分母 denominator,以字符串形式返回小数。

如果小数部分为循环小数,则将循环的部分括在括号内。

示例 1:

输入: numerator = 1, denominator = 2
输出: "0.5"


示例 2:

输入: numerator = 2, denominator = 1
输出: "2"

示例 3:

输入: numerator = 2, denominator = 3
输出: "0.(6)"

class Solution {
public:string fractionToDecimal(int numerator, int denominator) {	// 小数部分如果余数重复出现两次就表示该小数是循环小数了if (denominator == 0) return "";						if (numerator == 0) return "0";							string result;long long num = static_cast<long long>(numerator);      // 转换为longlong防止溢出long long denom = static_cast<long long>(denominator);if ((num>0) ^ (denom>0))result.push_back('-');          // 处理正负号,一正一负取负号      num = llabs(num); denom = llabs(denom);					  result.append(to_string(num / denom));					// 处理整数部分      // 处理小数部分num %= denom;											if (num == 0)return result;								result.push_back('.');									int index = result.size() - 1;							unordered_map<int, int> record;							// map用来记录出现重复数的下标,然后将'('插入到重复数前面就好了while (num&&record.count(num) == 0) {					// 小数部分:余数不为0且余数还没有出现重复数字record[num] = ++index;num *= 10;											// 余数扩大10倍,然后求商,和草稿本上运算方法是一样的result += to_string(num / denom);num %= denom;}if (record.count(num) == 1) {							// 出现循环余数,我们直接在重复数字前面添加'(',字符串末尾添加')'result.insert(record[num], "(");result.push_back(')');}return result;}
};

给定一个Excel表格中的列名称,返回其相应的列序号。

例如,

    A -> 1
B -> 2
C -> 3
...
Z -> 26
AA -> 27
AB -> 28 
...


示例 1:

输入: "A"
输出: 1


示例 2:

输入: "AB"
输出: 28


示例 3:

输入: "ZY"
输出: 701

class Solution {
public:int titleToNumber(string s) {int res = 0;for (auto &i: s) {res = 26*res + static_cast<int>(i - 'A' + 1);}return res;}
};

给定一个整数 n,返回 n! 结果尾数中零的数量。

示例 1:

输入: 3
输出: 0
解释: 3! = 6, 尾数中没有零。

示例 2:

输入: 5
输出: 1
解释: 5! = 120, 尾数中有 1 个零.

说明: 你算法的时间复杂度应为 O(log n) 。

class Solution {
public:int trailingZeroes(int n) {int res = 0;while (n >= 5) {res += n / 5;n /= 5;}return res; // return n/5+n/25+n/125+n/625+n/3125+n/15625+n/78125+n/390625+n/1953125+n/9765625+n/48828125+n/244140625+n/1220703125;}
};

 

  相关解决方案