从这篇博客开始记录我做LeetCode每一题的思路,目标是记录完全部的150多道题
就按从上往下的顺序吧,每题都会用几句话说明思路和贴代码
1. Reverse Words in a String
Given an input string, reverse the string word by word.
For example,
Given s = "the sky is blue
",
return "blue is sky the
".
思路:字符串处理,主要是考查空格的处理吧,用stringstream会异常简单
class Solution {
public:
void reverseWords(string &s) {
stringstream ss(s);
string word;
vector<string> words;
while(ss >> word) {
words.push_back(word);
}
s = "";
for(int i = words.size()-1; i >= 0; i--) {
s += words[i];
if(i) {
s += " ";
}
}
}
};
2. Evaluate Reverse Polish Notation
Evaluate the value of an arithmetic expression in Reverse Polish Notation.
Valid operators are +
, -
, *
, /
. Each operand may be an integer or another expression.
Some examples:
["2", "1", "+", "3", "*"] -> ((2 + 1) * 3) -> 9 ["4", "13", "5", "/", "+"] -> (4 + (13 / 5)) -> 6思路:逆波兰表达式求值,主要是考查栈的使用
class Solution {
public:
int evalRPN(vector<string> &tokens) {
stack<int> nums;
int op1, op2;
for(int i = 0; i < tokens.size(); i++) {
if(tokens[i] == "+") {
getOps(nums, op1, op2);
nums.push(op1 + op2);
}else if(tokens[i] == "-") {
getOps(nums, op1, op2);
nums.push(op1 - op2);
}else if(tokens[i] == "*") {
getOps(nums, op1, op2);
nums.push(op1 * op2);
}else if(tokens[i] == "/") {
getOps(nums, op1, op2);
nums.push(op1 / op2);
}else {
int num = atoi(tokens[i].c_str());
nums.push(num);
}
}
return nums.top();
}
void getOps(stack<int> &nums, int &op1, int &op2) {
op2 = nums.top();
nums.pop();
op1 = nums.top();
nums.pop();
}
};
class Solution {
public:
int evalRPN(vector<string> &tokens) {
stack<int> nums;
int op1, op2;
for(int i = 0; i < tokens.size(); i++) {
if(tokens[i] == "+") {
getOps(nums, op1, op2);
nums.push(op1 + op2);
}else if(tokens[i] == "-") {
getOps(nums, op1, op2);
nums.push(op1 - op2);
}else if(tokens[i] == "*") {
getOps(nums, op1, op2);
nums.push(op1 * op2);
}else if(tokens[i] == "/") {
getOps(nums, op1, op2);
nums.push(op1 / op2);
}else {
int num = atoi(tokens[i].c_str());
nums.push(num);
}
}
return nums.top();
}
void getOps(stack<int> &nums, int &op1, int &op2) {
op2 = nums.top();
nums.pop();
op1 = nums.top();
nums.pop();
}
};
3. Max Points on a Line
Given n points on a 2D plane, find the maximum number of points that lie on the same straight line.
思路:暴力枚举的办法做的,不知道有没有效率更高的办法。
我用分子分母两个整型数来表示一个斜率,避免了判断两个浮点数相等的精度问题。另外比较两个斜率的时候需要特判垂直y轴的情况。
我用分子分母两个整型数来表示一个斜率,避免了判断两个浮点数相等的精度问题。另外比较两个斜率的时候需要特判垂直y轴的情况。
/**
* Definition for a point.
* struct Point {
* int x;
* int y;
* Point() : x(0), y(0) {}
* Point(int a, int b) : x(a), y(b) {}
* };
*/
struct Slope {
int x;
int y;
Slope(int a, int b) : x(a), y(b) {}
friend bool operator<(const Slope& p1, const Slope& p2) {
if(p2.y == 0) {
return p1.y != 0;
}
if(p1.y == 0) {
return false;
}
return p1.x * p2.y < p2.x * p1.y;
}
bool operator==(const Slope& other) {
if(y == 0 || other.y == 0) {
return y == 0 && other.y == 0;
}
return x * other.y == other.x * y;
}
};
bool cmp(const pair<Slope, int> &p1, const pair<Slope, int> &p2) {
return p1.second < p2.second;
}
bool equal(const Point &p1, const Point &p2) {
return p1.x == p2.x && p1.y == p2.y;
}
class Solution {
public:
int maxPoints(vector<Point> &points) {
int maxNum = 0;
for(int i = 0; i < points.size(); i++) {
map<Slope, int> slopeCount;
int num = 0;
for(int j = 0; j < points.size(); j++) {
if(equal(points[i], points[j])) {
num++;
continue;
}
Slope slope(points[i].x - points[j].x, points[i].y - points[j].y);
map<Slope, int>::iterator it = slopeCount.find(slope);
if( it != slopeCount.end()) {
it->second = it->second + 1;
}else {
slopeCount[slope] = 1;
}
}
num = num + max_element(slopeCount.begin(), slopeCount.end(), cmp)->second;
if(num > maxNum) {
maxNum = num;
}
}
return maxNum;
}
};
4. Sort List
Sort a linked list in O(n log n) time using constant space complexity.
思路:时间复杂度为O(n log n),空间复杂度为O(1)的链表排序。使用的是stl里list的sort算法。算法的思想是:建立一些桶来保存一些有序的子链表,第一个桶的链表要么为空,要么只有一个元素,第二个桶的链表要么为空,要么只有两个元素……第N个桶的链表要么为空,要么只有2^(N-1)个元素。对原来链表的每一个元素,先将其插入第一个桶,如果桶满了就把第一个桶的链表往后传,如果第二个桶为空,那么链表就落在第二个桶,否则就将第一个桶的链表和第二桶的链表进行归并,对后面的桶重复调用这个过程……语言表达有点拗口,直接看代码可能还易懂一点。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *sortList(ListNode *head) {
ListNode* buckets[64];
memset(buckets, 0, sizeof(ListNode*)*64);
ListNode* sorted = NULL;
int nBuckets = 1;
while(head) {
int i = 0;
sorted = head;
head = head->next;
sorted->next = NULL;
while(NULL != buckets[i]) {
merge(sorted, buckets[i++]);
}
if(i >= nBuckets) {
nBuckets++;
}
buckets[i] = sorted;
}
sorted = buckets[0];
for(int i = 1; i < nBuckets; i++) {
if(buckets[i]) {
merge(sorted, buckets[i]);
}
}
return sorted;
}
void merge(ListNode* &head1, ListNode* &head2) {
if(NULL == head1 || NULL == head2) {
if(head2) {
swap(head1, head2);
}
return;
}
ListNode* resHead = NULL;
ListNode* resTail = NULL;
while(head1 && head2) {
ListNode* smaller = NULL;
if(head1->val <= head2->val) {
smaller = head1;
head1 = head1->next;
}else {
smaller = head2;
head2 = head2->next;
}
if(resHead) {
resTail->next = smaller;
resTail = resTail->next;
}else {
resTail = resHead = smaller;
}
}
if(head1) {
resTail->next = head1;
}else {
resTail->next = head2;
}
head1 = resHead;
head2 = NULL;
}
};
5. Insertion Sort List
Sort a linked list using insertion sort.
思路:链表的插入排序,没啥好说的,面试中要问到的话估计也是考查链表操作吧。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *insertionSortList(ListNode *head) {
ListNode* resHead = NULL;
while(head) {
ListNode* node2Insert = head;
head = head->next;
ListNode* postNode = NULL;
ListNode* curNode = resHead;
while(curNode != NULL && curNode->val < node2Insert->val) {
postNode = curNode;
curNode = curNode->next;
}
if(postNode) {
postNode->next = node2Insert;
}else {
resHead = node2Insert;
}
node2Insert->next = curNode;
}
return resHead;
}
};