我们把符合下列属性的数组 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;}
};