Leetcode Facebook Tag

// Minimum Path Sum
int minPathSum(vector<vector<int>>& grid) {
    if (grid.empty())
        return 0;
    const int n = grid.size(), m = grid[0].size();
    int f[n][m];
    f[0][0] = grid[0][0];
    for (int i = 1; i < n; i++)
        f[i][0] = f[i - 1][0] + grid[i][0];
    for (int j = 1; j < m; j++)
        f[0][j] = f[0][j - 1] + grid[0][j];
    for (int i = 1; i < n; i++)
        for (int j = 1; j < m; j++)
            f[i][j] = min(f[i - 1][j], f[i][j - 1]) + grid[i][j];
    return f[n - 1][m - 1];
}
// Minimum Two Path Sum
// Consider diagonal DP
// Search in Rotated Sorted Array
int search(vector<int>& nums, int target) {
    if (nums.empty())
        return -1;
        
    int low = 0, high = nums.size() - 1;
    while (low <= high) {
        int mid = (low + high) / 2;
        if (nums[mid] == target) {
            return mid;
        } else if (nums[low] <= nums[mid]) {
            if (nums[mid] > target && nums[low] <= target)
                high = mid - 1;
            else
                low = mid + 1;
        } else {
            if (nums[mid] < target && nums[high] >= target)
                low = mid + 1;
            else
                high = mid - 1;
        }
    }        
    return -1;
}
// Search in Rotated Sorted Array II
bool search(vector<int>& nums, int target) {
    if (nums.empty())
        return false;
        
    int low = 0, high = nums.size() - 1;
    while (low <= high) {
        int mid = (low + high) / 2;
        if (nums[mid] == target) {
            return true;
        } else if (nums[low] < nums[mid]) {
            if (nums[mid] > target && nums[low] <= target)
                high = mid - 1;
            else
                low = mid + 1;
        } else if (nums[low] > nums[mid]) {
            if (nums[mid] < target && nums[high] >= target)
                low = mid + 1;
            else
                high = mid - 1;
        } else {
            low++;
        }
    }        
    return false;
}
// Copy List with Random Pointer (LeetCode)
RandomListNode *copyRandomList(RandomListNode *head) {
    if (head == NULL)
        return NULL;
    unordered_map<RandomListNode*, RandomListNode*> cache;
    RandomListNode dummy(-1);
    RandomListNode *p = head, *q = &dummy;
    while (p) {
        q->next = new RandomListNode(p->label);
        q = q->next;
        cache[p] = q;
        p = p->next;
    }
    p = head;
    while (p) {
        if (p->random)
            cache[p]->random = cache[p->random];
        p = p->next;
    }
    return dummy.next;
}
// Binary Tree Level Order Traversal
vector<vector<int>> levelOrder(TreeNode* root) {
    queue<TreeNode*> q, p;
    vector<vector<int>> res;
    if (root)
        q.push(root);
    while (!q.empty()) {
        vector<int> level;
        while (!q.empty()) {
            level.push_back(q.front()->val);
            if (q.front()->left)
                p.push(q.front()->left);
            if (q.front()->right)
                p.push(q.front()->right);
            q.pop();
        }
        swap(p, q);
        res.push_back(level);
    }
    return res;
}
// Divide Two Integers
// Divide two integers without using multiplication, division and mod operator.
// If it is overflow, return MAX_INT.
// O((log n)^2)
int divide(int dividend, int divisor) {
    if (divisor == 0 || (dividend == INT_MIN && divisor == -1)) // Overflow
        return INT_MAX;
    bool negative = (divisor > 0) ^ (dividend > 0);
    long long dvd = dividend, dvs = divisor;
    dvd = abs(dvd); dvs = abs(dvs);
    int res = 0;
    while (dvd >= dvs) {
        long long temp = dvs;
        int mutiple = 1;
        while (dvd >= (temp << 1)) {
            temp <<= 1;
            mutiple <<= 1;
        }
        dvd -= temp;
        res += mutiple;
    }
    return negative ? -res : res;
}
// O(1)
int divide(int dividend, int divisor) {
    if (divisor == 0 || (dividend == INT_MIN && divisor == -1)) // Overflow
        return INT_MAX;
    bool negative = (divisor > 0) ^ (dividend > 0);
    // Transform to unsigned int
    unsigned int dvd = (dividend > 0) ? dividend : -dividend;
    unsigned int dvs = (divisor > 0) ? divisor : -divisor;
    // Shift W (= 32) times
    const int W = sizeof(int) * 8;
    int res = 0;
    for (int i = W - 1; i >= 0; i--) {
        if ((dvd >> i) >= dvs) { // dvd >= 2^i * dvs
            res = (res << 1) | 1; // res = 2 * res + 1
            dvd -= (dvs << i);
        } else
            res <<= 1; // res = 2 * res
    }
    return negative ? -res : res;
}
// Regular Expression Matching
// Implement regular expression matching with support for '.' and '*'.
// '.' Matches any single character.
// '*' Matches zero or more of the preceding element.
bool isMatch(string s, string p) {
    if (p.empty())
        return s.empty();
    if (p.size() > 1 && p[1] == '*') {
        return isMatch(s, p.substr(2)) || (!s.empty() && (s[0] == p[0] || p[0] == '.') && isMatch(s.substr(1), p));
    } else {
        return !s.empty() && (s[0] == p[0] || p[0] == '.') && isMatch(s.substr(1), p.substr(1));
    }
}
// Dynamic Programming
bool isMatch(string s, string p) {
    // f[i][j]: if s[0..i-1] matches p[0..j-1]
    int m = s.size(), n = p.size();
    vector<vector<bool>> f(m + 1, vector<bool>(n + 1, false));
    
    f[0][0] = true;
    for (int i = 1; i <= m; i++)
        f[i][0] = false;
    for (int j = 2; j <= n; j++)
        f[0][j] = (p[j - 1] == '*' && f[0][j - 2]);
    for (int j = 1; j <= n; j++) {
        for (int i = 1; i <= m; i++) {
            if (p[j - 1] == '*')
                f[i][j] = f[i][j - 2] || (f[i - 1][j] && (p[j - 2] == '.' || s[i - 1] == p[j - 2]));
            else
                f[i][j] = f[i - 1][j - 1] && (p[j - 1] == '.' || s[i - 1] == p[j - 1]);
        }
    }
    return f[m][n];    
}
// Wildcard Matching
// Implement wildcard pattern matching with support for '?' and '*'.
// '?' Matches any single character.
// '*' Matches any sequence of characters (including the empty sequence).
// Time Limit Exceeded
bool isMatch(const string& s, const string& p) {
    if (p.empty())
        return s.empty();
    if (p[0] == '*')
        return isMatch(s, p.substr(1)) || (!s.empty() && isMatch(s.substr(1), p));
    return !s.empty() && (p[0] == '?' || s[0] == p[0]) && isMatch(s.substr(1), p.substr(1));
}
// Time Limit Exceeded
bool isMatch(const string& s, const string& p) {
    if (p.empty())
        return s.empty();
    if (p[0] == '*') {
        int i = 1;
        while (i < p.size() && p[i] == '*')
            i++; // Skip continous '*'
        return isMatch(s, p.substr(i)) || (!s.empty() && isMatch(s.substr(1), p));
    }
    return !s.empty() && (p[0] == '?' || s[0] == p[0]) && isMatch(s.substr(1), p.substr(1));
}
// Dynamic Programming
bool isMatch(string s, string p) {
    // f[i][j]: is s[0..i-1] matches p[0..j-1]
    int m = s.size(), n = p.size();
    vector<vector<bool>> f(m + 1, vector<bool>(n + 1, false));
    f[0][0] = true;
    for (int i = 1; i <= m; i++)
        f[i][0] = false;
    for (int j = 1; j <= n; j++)
        f[0][j] = p[j - 1] == '*' && f[0][j - 1];
    for (int j = 1; j <= n; j++)
        for (int i = 1; i <= m; i++)
            if (p[j - 1] == '*')
                f[i][j] = f[i][j - 1] || f[i - 1][j];
            else
                f[i][j] = f[i - 1][j - 1] && (p[j - 1] == '?' || s[i - 1] == p[j - 1]);
    return f[m][n];
}
// Longest Consecutive Sequence
// Union-Find
int longestConsecutive(vector<int>& nums) {
    vector<int> parent(nums.size(), -1), rank(nums.size(), 1);
    unordered_map<int, int> cache;
    for (int i = 0; i < nums.size(); i++) {
        cache[nums[i]] = i;
    }
    for (auto iter = cache.begin(); iter != cache.end(); iter++) {
        int num = iter->first;
        if (cache.find(num + 1) != cache.end())
            Union(parent, rank, iter->second, cache[num + 1]);
    }
    int max_length = 0;
    for (int r : rank)
        max_length = max(max_length, r);
    return max_length;
}

int find(vector<int>& parent, int i) {
    if (parent[i] == -1)
        return i;
    parent[i] = find(parent, parent[i]); // uses path compression technique
    return parent[i];
}

void Union(vector<int>& parent, vector<int>& rank, int i, int j) {
    // can't use the function name union(), union is a c++ keyword
    int x = find(parent, i);
    int y = find(parent, j);
    if (x != y) {
        if (rank[x] <= rank[y]) {
            parent[x] = y;
            rank[y] += rank[x];
        }
        else {
            parent[y] = x;
            rank[x] += rank[y];
        }
    }
}
// 哈希表 只更新线段端点的长度
int longestConsecutive(vector<int>& nums) {
    int max_length = 0;
    unordered_map<int, int> sequence; // pair (num, length)
    for (int num : nums) {
        if (sequence.find(num) != sequence.end())
            continue;
        int left = (sequence.find(num - 1) != sequence.end()) ? sequence[num - 1] : 0;
        int right = (sequence.find(num + 1) != sequence.end()) ? sequence[num + 1] : 0;
        int length = 1 + left + right;
        sequence[num] = length;
        sequence[num - left] = length;
        sequence[num + right] = length;
        max_length = max(max_length, length);
    }
    return max_length;
}
// Edit Distance
int minDistance(string word1, string word2) {
    int m = word1.size(), n = word2.size();            
    int D[m + 1][n + 1];
    for (int i = 0; i <= m; i++)
        D[i][0] = i;
    for (int j = 1; j <= n; j++)
        D[0][j] = j;
    for (int i = 1; i <= m; i++) {
        for (int j = 1; j <= n; j++) {
            if (word1[i - 1] == word2[j - 1])
                D[i][j] = min(min(D[i - 1][j] + 1, D[i][j - 1] + 1), D[i - 1][j - 1]);
            else
                D[i][j] = min(min(D[i - 1][j] + 1, D[i][j - 1] + 1), D[i - 1][j - 1] + 1);
        }
    }
    return D[m][n];
}
// Populating Next Right Pointers in Each Node II
// 既然上一层的节点已经通过next指针连起来了,那么就只要能得到上一层的第一个节点就可以依次把上一层节点的子节点串联起来了
// 通过添加一个dummy假节点来标记当前行的首节点
void connect(TreeLinkNode *root) {
    while (root) {
        TreeLinkNode dummy(-1);
        TreeLinkNode *p = &dummy, *q = root;
        while (q) {
            if (q->left) {
                p->next = q->left;
                p = p->next;
            }
            if (q->right) {
                p->next = q->right;
                p = p->next;
            }
            q = q->next;
        }
        root = dummy.next;
    }
}
// Binary Search Tree Iterator
// In-order Traveral Binary Tree Iterator
class BSTIterator {
public:
    BSTIterator(TreeNode *root) {
        TreeNode *p = root;
        while (p) {
            s.push(p);
            p = p->left;
        }
    }
    /** @return whether we have a next smallest number */
    bool hasNext() {
        return !s.empty();
    }
    /** @return the next smallest number */
    int next() {
        int res = s.top()->val;
        TreeNode *p = s.top()->right;
        if (p) {
            while (p) {
                s.push(p);
                p = p->left;
            }
        } else {
            p = s.top();
            s.pop();
            while (!s.empty() && p == s.top()->right) {
                p = s.top();
                s.pop();
            }
        }
        return res;
    }
private:
    stack<TreeNode*> s;
};
class BSTIterator {
public:
    BSTIterator(TreeNode *root) {
        TreeNode *p = root;
        while (p) {
            s.push(p);
            p = p->left;
        }
    }
    /** @return whether we have a next smallest number */
    bool hasNext() {
        return !s.empty();
    }
    /** @return the next smallest number */
    int next() {
        int res = s.top()->val;
        TreeNode *p = s.top()->right;
        s.pop();
        while (p) {
            s.push(p);
            p = p->left;
        }
        return res;
    }
private:
    stack<TreeNode*> s;
};
// Kth Largest Element in an Array
// Sort 
// O(N lg N) running time + O(1) memory
class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        sort(nums.begin(), nums.end());
        return nums[nums.size() - k];
    }
};
// Use a min oriented priority queue storing the K-th largest values
// O(N lg K) running time + O(K) memory
class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        priority_queue<int, vector<int>, greater<int>> minpq;
        for (int i = 0; i < k; i++)
            minpq.push(nums[i]);
        for (int i = k; i < nums.size(); i++)
            if (nums[i] > minpq.top()) {
                minpq.pop();
                minpq.push(nums[i]);
            }
        return minpq.top();
    }
};
// Use the selection algorithm (based on the partion method - the same one as used in quicksort)
// O(N) best case / O(N^2) worst case / amortized O(N) running time + O(1) memory
class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        random_shuffle(nums.begin(), nums.end());        
        k = nums.size() - k;
        int low = 0, high = nums.size() - 1;
        while (low < high) {
            int mid = partition(nums, low, high);
            if (mid < k)
                low = mid + 1;
            else if (mid > k)
                high = mid - 1;
            else
                break;                
        }
        return nums[k];
    }
    int partition(vector<int>& nums, int low, int high) {
        int pivot = nums[low], i = low;
        // nums[0..i] <= pivot, nums[i+1..j-1] > pivot, nums[j..n-1] unknown
        for (int j = low + 1; j <= high; j++) {
            if (nums[j] <= pivot)
                swap(nums[++i], nums[j]);
        }
        swap(nums[low], nums[i]);
        return i;
    }
};
// Minimum Window Substring
// Hash Table + Two Pointers + String
string minWindow(string s, string t) {
    string res = "";
    unordered_map<char, int> pattern, window;
    int count = 0, min_window = INT_MAX;
    for (char c : t)
        pattern[c]++;
    for (int start = 0, end = 0; end < s.size(); end++) {
        char c = s[end];
        if (pattern.find(c) != pattern.end()) {
            window[c]++;
            if (window[c] <= pattern[c])
                count++;
            if (count == t.size()) {
                while (pattern.find(s[start]) == pattern.end() || window[s[start]] > pattern[s[start]]) {
                    if (pattern.find(s[start]) != pattern.end())
                        window[s[start]]--;
                    start++;
                }
                if (end - start + 1 < min_window) {
                    min_window = end - start + 1;
                    res = s.substr(start, min_window);
                }       
            }
        }
    }
    return res;
}
// Longest Substring Without Repeating Characters
// Hash Table + Two Pointers + String
class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        unordered_map<char, int> cache;
        int start = 0, max_length = 0;
        for (int end = 0; end < s.size(); end++) {
            if (cache.find(s[end]) == cache.end() || cache[s[end]] < start) {
                cache[s[end]] = end;
                max_length = max(max_length, end - start + 1);
            } else {
                start = cache[s[end]] + 1;
                cache[s[end]] = end;
                max_length = max(max_length, end - start + 1);
            }
        }
        return max_length;
    }
};
// Decode Ways
int numDecodings(string s) {
    if (s.empty() || s[0] == '0')
        return 0;
    vector<int> f(s.size() + 1);
    f[0] = 1;
    f[1] = 1;
    for (int i = 2; i <= s.size(); i++) {
        if (s[i - 1] == '0') {
            if (!(s[i - 2] == '1' || s[i - 2] == '2'))
                return 0;
            f[i] = f[i - 2];    
        } else if (s[i - 1] >= '1' && s[i - 1] <= '6') {
            f[i] = ((s[i - 2] == '1' || s[i - 2] == '2') ? (f[i - 1] + f[i - 2]) : f[i - 1]);
        } else {
            f[i] = ((s[i - 2] == '1') ? (f[i - 1] + f[i - 2]) : f[i - 1]);
        }          
    }
    return f[s.size()];
}
// LCA of Binary Tree
// Find the paths to p and q and then find the last node where the paths match
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
    if (root == NULL || root == p || root == q)
        return root;
    vector<TreeNode*> path_p, path_q;
    dfs(root, p, q, {}, path_p, path_q);
    int i = 0;
    while (path_p[i] == path_q[i])
        i++;
    return path_p[i - 1];
}
void dfs(TreeNode* root, TreeNode* p, TreeNode* q, vector<TreeNode*> path, vector<TreeNode*> &path_p, vector<TreeNode*> &path_q) {
    if (root == NULL)
        return;
    path.push_back(root);
    if (root == p)
        path_p = path;
    if (root == q)
        path_q = path;
    dfs(root->left, p, q, path, path_p, path_q);
    dfs(root->right, p, q, path, path_p, path_q);
}
TreeNode* lowestCommonAncestor(TreeNode *root, TreeNode *p, TreeNode *q) {
    if (root == NULL || root == p || root == q)
        return root;
    TreeNode* l = lowestCommonAncestor(root->left, p, q);
    TreeNode* r = lowestCommonAncestor(root->right, p, q);
    if (l != NULL && r != NULL)
        return root;
    if (l != NULL)
        return l;
    return r;
}
// Task Scheduler
int leastInterval(vector<char>& tasks, int n) {
    vector<int> count(26);
    for (char c : tasks)
        count[c - 'A']++;
    sort(count.begin(), count.end());
    int timer = 0;
    while (count[25] > 0) {
        for (int i = 0, j = 25; i < n + 1; i++, j--) {
            if (j >= 0 && count[j] > 0)
                count[j]--;
            else if (count[25] == 0)
                break;
            timer++;
        }
        sort(count.begin(), count.end());
    }
    return timer;
}
int leastInterval(vector<char>& tasks, int n) {
    int count[26];
    for (int i = 0; i < 26; i++)
        count[i] = 0;
    for (char c : tasks)
        count[c - 'A']++;
    sort(count, count + 26, greater<int>()); // sort in decreasing order
    int timer = 0;
    int j = 25;
    while (j >= 0 && count[j] == 0)
        j--;
    while (j >= 0) {
        timer += ((j >= n || count[0] > 1) ? n + 1 : j + 1); // j + 1 means #tasks left
        for (int i = 0; i <= j && i < n + 1; i++)
            count[i]--;
        sort(count, count + j + 1, greater<int>());
        while (j >= 0 && count[j] == 0)
            j--;
    }
    return timer;
}
// Combination Sum
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
    vector<vector<vector<int>>> sums(1 + target);
    sums[0] = vector<vector<int>>(1); // sums[0].push_back(vector<int>());
    for (int num : candidates) {
        for (int i = num; i <= target; i++) {
            vector<vector<int>> copy(sums[i - num].begin(), sums[i - num].end());
            for (int j = 0; j < copy.size(); j++)
                copy[j].push_back(num);
            sums[i].insert(sums[i].end(), copy.begin(), copy.end());
        }
    }
    return sums[target];
}
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
    vector<vector<int>> res;
    vector<int> path;
    combinationSum(0, candidates, target, path, res);
    return res;
}
void combinationSum(int i, vector<int>& candidates, int target, vector<int> &path, vector<vector<int>> &res) {
    if (i == candidates.size()) {
        if (target == 0)
            res.push_back(path);
        return;
    }
    for (int num = 0; num <= target; num += candidates[i]) {
        combinationSum(i + 1, candidates, target - num, path, res);
        path.push_back(candidates[i]);
    }
    for (int num = 0; num <= target; num += candidates[i])
        path.pop_back();
}
// Flatten Binary Tree to Linked List
void flatten(TreeNode* root) {
    TreeNode *p = root;
    stack<TreeNode*> s;
    while (p) {
        if (p->right)
            s.push(p->right);
        if (p->left) {
            p->right = p->left;
            p->left = NULL;
        } else if (!s.empty()) {
            p->right = s.top();
            s.pop();
        }
        p = p->right;
    }
}
// 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".
// For C programmers: Try to solve it in-place in O(1) space.
/* Clarification:
What constitutes a word?
A sequence of non-space characters constitutes a word.
Could the input string contain leading or trailing spaces?
Yes. However, your reversed string should not contain leading or trailing spaces.
How about multiple spaces between two words?
Reduce them to a single space in the reversed string.
*/
void reverseWords(string &s) {
    vector<string> words;
    string cur = "";
    for (char c : s) {
        if (c == ' ') {
            if (cur != "")
                words.push_back(cur);
            cur = "";
        } else {
            cur += c;
        }
    }
    if (cur != "")
        words.push_back(cur);
    if (words.empty()) {
        s = "";
        return;
    }
    reverse(words.begin(), words.end());
    s = words[0];
    for (int i = 1; i < words.size(); i++)
        s += (' ' + words[i]);
}
// In place simple solution
// First, reverse the whole string, then reverse each word.
void reverseWords(string &s) {
    // i: the beginning of one word, j: the end of one word(including one trailing space)
    // k: the current position available for insertion
    reverse(s.begin(), s.end());
    int i = 0, j, k = 0; 
    while (i < s.size() && s[i] == ' ')
        i++;
    while (i < s.size()) {
        if (k != 0)
            s[k++] = ' ';
        j = i;
        while(j < s.size() && s[j] != ' ')
            s[k++] = s[j++];
        reverse(s.begin() + k - (j - i), s.begin() + k);
        i = j + 1;
        while (i < s.size() && s[i] == ' ')
            i++;
    }
    s.erase(s.begin() + k, s.end()); // s.erase(k);
}
// Kth Smallest Element in a Sorted Matrix
// Heap
struct Element {
    int i, j, num;
    Element(int i, int j, int num): i(i), j(j), num(num) {}
    bool operator< (const Element &other) const {
        return num > other.num;
    }
};
int kthSmallest(vector<vector<int>>& matrix, int k) {
    const int n = matrix.size(), m = matrix[0].size();
    priority_queue<Element> pq;
    for (int i = 0; i < n; i++)
        pq.push(Element(i, 0, matrix[i][0]));
    for (int ii = 0; ii < k - 1; ii++) {
        Element e = pq.top();
        pq.pop();
        if (e.j + 1 < m)
            pq.push(Element(e.i, e.j + 1, matrix[e.i][e.j + 1]));
    }
    return pq.top().num;
}
// Binary Search
int kthSmallest(vector<vector<int>>& matrix, int k) {
    // Find the smallest number num which #{numbers in the matrix <= num} >= k
    const int n = matrix.size(), m = matrix[0].size();
    int low = matrix[0][0], high = matrix[n - 1][m - 1];
    while (low < high) {
        int mid = low + (high - low) / 2;
        int count = 0, i = n - 1, j = 0;
        while (i >= 0 && j < m) {
            if (matrix[i][j] <= mid) {
                count += (i + 1);
                j++;
            } else {
                i--;
            }
        }
        if (count >= k)
            high = mid;
        else
            low = mid + 1;
    }
    return low;
}
// Largest Rectangle in Histogram
int largestRectangleArea(vector<int>& heights) {
    stack<int> s;
    heights.push_back(0);
    
    int max_sum = 0, i = 0;
    while (i < heights.size()) {
        if (s.empty() || heights[i] > heights[s.top()]) {
            s.push(i);
            i++;
        } else {
            int j = s.top();
            s.pop();
            max_sum = max(max_sum, heights[j] * (s.empty() ? i : (i - 1 - s.top())));
        }
    }
    return max_sum;
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343

推荐阅读更多精彩内容