Commit bd4bedd1 authored by anqiwa's avatar anqiwa 😲
Browse files

initial commit

parents
/*
* @lc app=leetcode id=1 lang=cpp
*
* [1] Two Sum
*/
#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
using namespace std;
// @lc code=start
class Solution
{
public:
vector<int> twoSum(vector<int> &nums, int target)
{
//* <diff, val>
unordered_map<int, int> diff_map;
vector<int> res; // record the index
res.resize(2);
for (int i = 0; i < nums.size(); ++i)
{
auto it = diff_map.find(nums[i]);
if (it == diff_map.end()) // if we don't find it
{
diff_map[target - nums[i]] = i;
}
else
{
res[0] = it->second;
res[1] = i;
}
} //for
return res;
} //twoSum()
};
// @lc code=end
/*
* @lc app=leetcode id=109 lang=cpp
*
* [109] Convert Sorted List to Binary Search Tree
*/
// @lc code=start
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution
{
public:
TreeNode *sortedListToBST(ListNode *head)
{
//* recurseively insert to the mid point to the tree
if (!head)
return nullptr;
return toBstHelper(head, nullptr);
}
// [begin,end)
TreeNode *toBstHelper(ListNode *begin, ListNode *end)
{
// base case
if (begin == end)
return nullptr;
//* find the mid point
ListNode *slow = begin;
ListNode *fast = begin;
while (fast->next != end && fast->next->next != end)
{
fast = fast->next->next;
// temp = slow; // record the node before slow
slow = slow->next;
} //while
// slow now is at the mid point
TreeNode *root = new TreeNode(slow->val);
root->left = toBstHelper(begin, slow);
root->right = toBstHelper(slow->next, end);
return root;
}
};
// @lc code=end
/*
* @lc app=leetcode id=1124 lang=cpp
*
* [1124] Longest Well-Performing Interval
*/
// @lc code=start
class Solution
{
public:
int longestWPI(vector<int> &hours)
{
// 使用单调栈和前缀和
const int n = hours.size();
int res = 0;
//use a vector convert the problem to presum
// tiring day -> 1
// non tiring day -> -1
vector<int> presum;
presum.reserve(n + 1);
presum.push_back(0); // add one extra 0
int sum = 0; // accumulate presum
for (const auto hr : hours)
{
if (hr > 8)
{
sum += 1;
presum.push_back(sum);
}
else
{
sum += -1;
presum.push_back(sum);
}
}
stack<int> Stack; // pos, mono de.
for (int i = 0; i < presum.size(); ++i)
{
if (Stack.empty() || presum[Stack.top()] > presum[i])
Stack.push(i);
} //for
for (int j = presum.size() - 1; j >= 0; --j)
{
while (!Stack.empty() && presum[Stack.top()] < presum[j])
{
res = max(res, j - Stack.top());
Stack.pop();
} //while
} //for
return res;
}
};
// @lc code=end
/*
* @lc app=leetcode id=1190 lang=cpp
*
* [1190] Reverse Substrings Between Each Pair of Parentheses
*/
// @lc code=start
class Solution
{
stack<int> Stack; // store the pos of (
public:
string reverseParentheses(string s)
{
// this solution is O(n^2)
// 韩神解法 O(n)
//https://github.com/wisdompeak/LeetCode/blob/master/Stack/1190.Reverse-Substrings-Between-Each-Pair-of-Parentheses/1190.Reverse-Substrings-Between-Each-Pair-of-Parentheses_O(N).cpp
string res;
for (auto ch : s)
{
if (isalpha(ch))
res.push_back(ch);
else if (ch == '(')
Stack.push(res.size());
else
{
int i = Stack.top();
Stack.pop();
reverse(res.begin() + i, res.end());
}
}
return res;
}
};
// @lc code=end
/*
* @lc app=leetcode id=141 lang=cpp
*
* [141] Linked List Cycle
*/
// @lc code=start
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution
{
public:
bool hasCycle(ListNode *head)
{
if (!head)
return false;
ListNode *slow = head;
ListNode *fast = head;
while (fast->next && fast->next->next)
{
// 一定要先移动后检查,因为初始一致
fast = fast->next->next;
slow = slow->next;
if (fast == slow)
return true;
}
return false;
}
};
// @lc code=end
/*
* @lc app=leetcode id=142 lang=cpp
*
* [142] Linked List Cycle II
*/
// @lc code=start
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution
{
public:
ListNode *detectCycle(ListNode *head)
{
//* idea: fast ptr && slow ptr
//* first determine if exists a cycle (if they meet)
//* from meet point to begin point is from h to begin point
// determine if a cycle
ListNode *fast = head;
ListNode *slow = head;
bool isMeet = false;
// if empty
if (!head)
return nullptr;
while (fast->next && fast->next->next)
{
fast = fast->next->next;
slow = slow->next;
if (fast == slow)
{
isMeet = true;
break;
}
} // while
if (!isMeet)
{
return nullptr;
}
// now fast and slow are at the point they meet;
while (head != slow)
{
head = head->next;
slow = slow->next;
} //while
return head;
}
};
// @lc code=end
/*
* @lc app=leetcode id=143 lang=cpp
*
* [143] Reorder List
*/
// @lc code=start
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution
{
public:
void reorderList(ListNode *head)
{
//* this problem has 3 parts
//* 1. find the mid of the given list (fast-slow ptrs)
//* 2. break thae mid and reverse the second list
//* 3. alternatively take nodes to construct a new list
if (!head || !head->next)
return;
// find the mid ptr
ListNode *mid = nullptr;
ListNode *fast = head, *slow = head;
while (fast->next != nullptr &&
fast->next->next != nullptr)
{
fast = fast->next->next;
slow = slow->next;
} // while
mid = slow;
// break from mid and reverse the second list
ListNode *l2 = mid->next;
mid->next = nullptr;
// reverse the list by iterative method
// in this case l2 is head;
ListNode *prev = nullptr, *next;
ListNode *curr = l2;
while (l2 != nullptr)
{
next = l2->next;
l2->next = prev;
prev = l2;
l2 = next;
} //while
l2 = prev;
ListNode *l1 = head;
// alternatively take node to construct new list;
while (l2->next || l1->next)
{
if (l1)
{
next = l1->next;
l1->next = l2;
l1 = next;
}
if (l2)
{
next = l2->next;
l2->next = l1;
l2 = next;
}
} //while
}
};
// @lc code=end
/*
* @lc app=leetcode id=148 lang=cpp
*
* [148] Sort List
*/
// @lc code=start
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution
{
public:
ListNode *sortList(ListNode *head)
{
// only 0/1 element in the linked lists
if (!head || !head->next)
return head;
//use fast-slow ptrs to find mid
ListNode *fast = head;
ListNode *slow = head;
while (fast->next && fast->next->next)
{
fast = fast->next->next;
slow = slow->next;
} // while
// break the list
ListNode *slowNext = slow->next;
slow->next = nullptr;
ListNode *left = sortList(head);
ListNode *right = sortList(slowNext);
return merge(left, right);
}
//* huahua's version of merge is better
ListNode *merge(ListNode *left, ListNode *right)
{
ListNode dummy(0);
ListNode *dummy_ptr = &dummy;
while (left && right)
{
if (left->val < right->val)
{
ListNode *next = left->next;
left->next = nullptr;
dummy_ptr->next = left;
dummy_ptr = dummy_ptr->next;
left = next;
}
else
{
ListNode *next = right->next;
right->next = nullptr;
dummy_ptr->next = right;
dummy_ptr = dummy_ptr->next;
right = next;
} // end if
} // while
while (right)
{
ListNode *next = right->next;
right->next = nullptr;
dummy_ptr->next = right;
dummy_ptr = dummy_ptr->next;
right = next;
} // while
while (left)
{
ListNode *next = left->next;
left->next = nullptr;
dummy_ptr->next = left;
dummy_ptr = dummy_ptr->next;
left = next;
} //while
return dummy.next;
}
};
// @lc code=end
/*
* @lc app=leetcode id=15 lang=cpp
*
* [15] 3Sum
*/
// @lc code=start
class Solution
{
public:
vector<vector<int>> threeSum(vector<int> &nums)
{
const int n = nums.size();
vector<vector<int>> res;
//*sort nums for 2 ptr
sort(nums.begin(), nums.end());
for (int i = 0; i < n; ++i)
{
//* remove duplicate
if (i && nums[i] == nums[i - 1])
continue;
int j = i + 1, k = n - 1;
int t = -nums[i];
while (j < k)
{
int sum = nums[j] + nums[k];
if (sum > t)
--k;
else if (sum < t)
++j;
else
{
//* we find a ans + remove duplicate
res.push_back({nums[i], nums[j], nums[k]});
while (j < k && nums[j] == nums[j + 1])
++j;
while (j < k && nums[k] == nums[k - 1])
--k;
++j;
--k;
}
} // while
} //for
return res;
} //3sum()
};
// @lc code=end
/*
* @lc app=leetcode id=151 lang=cpp
*
* [151] Reverse Words in a String
*/
#include <iostream>
#include <string>
#include <sstream> // std::istringstream
#include <stack>
using namespace std;
// @lc code=start
class Solution
{
public:
string reverseWords(string &s)
{
if (!s.size())
return "";
istringstream ss(s);
string word;
string res;
while (ss >> word)
{
if (res.empty())
{
res = word;
}
else
{
res = word + " " + res;
}
}
return res;
}
};
// @lc code=end
/*
* @lc app=leetcode id=1544 lang=cpp
*
* [1544] Make The String Great
*/
// @lc code=start
class Solution
{
public:
string makeGood(string s)
{
// 使用stack的思维,但是不一定需要stack
if (s.size() <= 1)
return s;
string res;
for (char c : s)
{
int diff = 'a' - 'A';
if (res.size() &&
abs(res.back() - c) == diff)
res.pop_back();
else
res.push_back(c);
}
return res;
}
};
// @lc code=end
/*
* @lc app=leetcode id=155 lang=cpp
*
* [155] Min Stack
*/
// @lc code=start
class MinStack
{
public:
/** initialize your data structure here. */
MinStack() : curr_min{INT_MAX} {}
//* store the diff between old min and input val
void push(int val)
{
if (data.empty())
{