- 概要の間隔
繰り返し要素のない順序付けられた整数配列を指定すると、配列の範囲の概要を返します。
とても簡単な質問です
class Solution {
public:
vector<string> summaryRanges(vector<int>& nums)
{
vector<string> ans;
for (int i = 0; i < nums.size(); i++)
{
string str = to_string(nums[i]);
int pos = i;
while (i < nums.size() - 1 && nums[i] + 1 == nums[i + 1])
{
i++; //数字连续
}
if (pos != i) //若有增加
{
str += "->" + to_string(nums[i]);
}
ans.push_back(str);
}
return ans;
}
};
- モード2を
見つけるサイズnの配列を指定して、appear n / 3⌋回より多く出現するすべての要素を見つけます。
ムーアの投票により解決されました。マッピング配列が直接使用される場合、スペースの複雑さは要件を満たしていません
/*
时间复杂度为:O(n)
空间复杂度为:O(1)
*/
class Solution {
public:
vector<int> majorityElement(vector<int>& nums) {
int len = nums.size();
vector<int>res, cands, cnts;
if(len == 0){
//没有元素,直接返回空数组
return res;
}
cands.assign(2, nums[0]);
cnts.assign(2, 0);
//第1阶段 成对抵销
for(auto num: nums){
bool flag = false;
for(int i = 0; i < cands.size(); ++i){
if(num == cands[i]){
++cnts[i];
flag = true;
break;
}
}
if(!flag){
bool flag2 = false;
for(int j = 0; j < cands.size(); ++j){
if(cnts[j] == 0){
flag2 = true;
cands[j] = num;
cnts[j]++;
}
}
if(!flag2){
for(int j = 0; j < cnts.size(); ++j){
--cnts[j];
}
}
}
}
//第2阶段 计数 数目要超过三分之一
cnts[0] = cnts[1] = 0;
if(cands[0] == cands[1])
cands.pop_back();
for(auto num:nums){
for(int i = 0; i < cands.size(); ++i){
if(cands[i] == num){
++cnts[i];
break;
}
}
}
for(int i = 0; i < cands.size(); ++i){
if(cnts[i] > len / 3){
res.push_back(cands[i]);
}
}
return res;
}
};
バイナリ検索ツリーのK番目に小さい要素バイナリ検索ツリーが与えられた場合、関数kthSmallestを記述して、その中でk番目に小さい要素を見つけます。
最も簡単な方法は、再帰または反復を使用して中位のトラバーサルを配置することです。k番目の要素を取得するだけです。その中で、反復はk番目のものを見つけ、すぐに戻るのを停止できるため、反復は再帰よりも優れています。
class Solution {
int m_cnt = 0, m_ret = 0;
public:
int kthSmallest(TreeNode* root, int k)
{
__midOrder(root, k);
return m_ret;
}
private:
void __midOrder(TreeNode *root, int k)
{
if (root == NULL) return;
__midOrder(root->left, k);
m_cnt++;
if (m_cnt == k) m_ret = root->val;
__midOrder(root->right, k);
}
};
class Solution {
int m_cnt = 0, m_ret = 0;
public:
int kthSmallest(TreeNode* root, int k)
{
return __midOrder(root, k);
}
private:
int __midOrder(TreeNode *root, int k)
{
stack<TreeNode *> s;
TreeNode *cur = root;
while (s.size() || cur)
{
while (cur)
{
s.push(cur);
cur = cur->left;
}
cur = s.top();
s.pop();
m_cnt++;
if (m_cnt == k) return cur->val;
cur = cur->right;
}
return 0;
}
};
- 2のべき乗は
簡単な質問です
class Solution {
public:
bool isPowerOfTwo(int n) {
if (n <= 0) return false;
while (n > 1)
{
if (n % 2 != 0)
return false;
else
n = n / 2;
}
return true;
}
};
- スタックでキューを実装する
前のキューと同様に、必要なスタックは1つだけです。
class MyQueue {
public:
stack<int> inStack;
stack<int> outStack;
MyQueue() {
}
void push(int x) {
inStack.push(x);
}
int pop() {
cheak();
int a=outStack.top();
outStack.pop();
return a;
}
int peek() {
cheak();
return outStack.top();
}
bool empty() {
return inStack.empty()&&outStack.empty();
}
void cheak()
{
if(outStack.empty())
{
while(!inStack.empty())
{
outStack.push(inStack.top());
inStack.pop();
}
}
}
};
/*
* Your MyQueue object will be instantiated and called as such:
* MyQueue* obj = new MyQueue();
* obj->push(x);
* int param_2 = obj->pop();
* int param_3 = obj->peek();
* bool param_4 = obj->empty();
*/
- 数1の数
整数nが与えられた場合、n以下のすべての非負整数における数1の出現数を計算します。
Iは1からnまでトラバースされ、各反復の10倍展開i はビット数を
(n/(i*10))∗i
示し(i*10)
ます。
min(max((n mod (i*10)} )-i+1, 0), i)})
追加の桁が必要な桁の(i*10)
1 の数を示します。
class Solution {
public:
int countDigitOne(int n)
{
int countr = 0;
for (long long i = 1; i <= n; i *= 10) {
long long divider = i * 10;
countr += (n / divider) * i + min(max(n % divider - i + 1, 0LL), i);
}
return countr;
}
};
- 回文リンクリスト
リンクリストが回文リンクリストかどうか判断してください。この問題をO(n)時間の複雑さとO(1)空間の複雑さで解決できますか?
スペースの複雑さO(1)は、スタックストレージまたは再帰検索を使用できないことを示しています。したがって、ここでのアプローチは、最初に高速ポインタと低速ポインタを使用して中間ノードを取得し、高速ポインタと低速ポインタの移動中に前半を逆にし、次に後半と前半を比較することです。値が等しいかどうか。中間ノードのパリティの判断に注意してください
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
bool isPalindrome(ListNode* head) {
if(!head || !head->next)
return 1;
ListNode *fast = head, *slow = head;
ListNode *p, *pre = NULL;
while(fast && fast->next){
p = slow;
slow = slow->next; //快慢遍历
fast = fast->next->next;
p->next = pre; //翻转
pre = p;
}
if(fast) //奇数个节点时跳过中间节点
slow = slow->next;
while(p){
//前半部分和后半部分比较
if(p->val != slow->val)
return 0;
p = p->next;
slow = slow->next;
}
return 1;
}
};