LeetCode题解其一(题1~题5)

从这篇博客开始记录我做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();
    }
};


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轴的情况。
/**
 * 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;
    }
};




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值