LeetCode Record C++

本文内容为练习LeetCode题目时的解题思路和不同算法的记录,实现语言为C++,代码保存在Github,均已在LeetCode提交AC且均含最优解并尽多尝试多解,单击标题以查看,持续更新,暂时只进行Top Interview Questions列表下题目。


现在觉得全写在一篇文章里面过于臃肿且不易查找,我又不想做个目录出来,那样岂不是更臃肿?因此如果刷第二遍或者准备停止刷LeetCode的话我会把这篇记录按题目拆分出来,也许会根据专题整理一下多一级目录,也许不会,简书的文集内不能再分级实在是一个很不好的缺点。[2018.05.09]

2018.05.11 update:
378. Kth Smallest Element in a Sorted Matrix
#56/145 solved#

1. Two Sum

除了双重遍历外,可以用hash的方式空间换时间,遍历过程中依次存放每个元素的值及其下标,如果当前元素的互补数(target-nums[i])在哈希表中存在则可得结果。

7. Reverse Integer

反转32位整数,需要考虑溢出问题。
原本用了long long来判断溢出,但后来发现有个家伙用溢出后的数做逆操作与上次结果比较不同来判断,十分有才,判断方式:
if ((aux_ret - x % 10) / 10 != ret) return 0;

13. Roman to Integer

罗马数字的规则对左减数字有限制(仅限于I/X/C且不能跨位相减),但右加数字没有,因此逆序做转换是AC的但顺序转换会WA(eg:MCMXCVI-1996)。

14. Longest Common Prefix

求一组字符串的最长相同前缀(LCP),个人给出两种解决方案,一种是横向地顺序遍历每个字符串与之前得到的LCP计算新的LCP,这种思想可以划分到动态规划中;另外一种方法是考虑整体类似于一个不完全的字符矩阵,那么我们可以纵向地从第一列开始逐列对比,全部相同就把该字符加到LCP中,不同就可以返回LCP了。
此外LeetCode还给出了分治法和二分查找法的解决方案,思想也很简单,但是不如前面两种方法简洁也没有明显优势,因此了解即可。

20. Valid Parentheses

学过编译原理的应该都知道怎么做,可以利用栈来进行括号匹配,有无法匹配的括号那么说明语法错误。

21. Merge Two Sorted Lists

第一种迭代方案是在需要合并时交换当前节点和比较节点,也是自己第一时间想到的做法;
第二种迭代方案是按大小顺序依次合并两个链表的每个节点到新链表;
第三种是递归的做法,从第一个节点开始依次合并每个最小节点,注意此方法不是尾递归,不适用于过长链表合并,可能会导致栈溢出,但该题目目前的测试用例规模还没有到临界点,可以AC。

22. Generate Parentheses

穷举n对圆括号可以构成的所有合法字符序列。
第一个想到的方法是把每个合法字符串作为一行形成一个矩阵纵向遍历,每次添加一个括号,对于每行的字符串,如果下一个可能添加的括号有两种选择,则拷贝其一到矩阵最后一行;
第二个方法是递归回溯,可以把回溯过程看做一棵二叉树,每次递归调用会拷贝一次当前字符串然后判断下次添加的括号可能性(分支),直到n对括号全部添加完成后(叶子节点)把当前字符串加入结果集;
第三个方法LeetCode上称之为Closure number但我觉得像是分治法(还是DP?),这个方法比较trickier,LeetCode上的解释也没太明白,这里就说一下个人理解,我们可以把一个合法的括号字符串看做一个闭包,它必然起于左括号止于右括号,且每个合法括号串都可以从某个位置分为两个同样合法的括号串(包括空串),因此对于给定的n所可能构造的所有括号串都可以一步步划分为两个子闭包并解构(去掉头尾的一对左右括号)直到最小闭包——空串为止。基于以上分析,我们就可以从空串开始逆向一步步对两个子闭包之一构造新的闭包(在头尾各添加一个左/右括号)然后合并,至于构造对象是谁都是可以的,也就是代码中的核心部分:

ret.push_back(left + '(' + right + ')');// 以right闭包为构造对象
//ret.push_back('(' + left + ')' + right);// 或以left闭包为构造对象

26. Remove Duplicates from Sorted Array

一开始题意理解错误了..题目要求是在O(1)复杂度的前提下得到输入排序数组去重后的结果,注意要用输入数组保存去重后的数组,输出的长度是去重后数组的长度。顺便一提in-place算法一般多采用替代或者交换的方式来实现,我的解法是遍历整个数组依次把第n个不重复的元素替换数组下标为n-1的元素得到最终结果。

28. Implement strStr()

字符串匹配函数的实现,逐字匹配过于低效,用hash方式空间换时间。
也可以用KMP算法来实现,其本质是对于模式串中前后缀相同的子串减少匹配次数,回头实现了之后补充源码再梳理一下KMP的原理。

38. Count and Say

根据上一次的字符串计算下次的结果,迭代法,维持一个相同数字计数器,当遇到不同数字或者字符串结尾时把这个数字和计数器的值附加到新字符串后面。

46. Permutations

给定一个无重复整数数组,穷举其所有排列。

  1. 递归回溯
    思路比较清晰,每次定位一个数字,锁上这个数字在的位置(剩余数字不可以排在这里),每次上锁后记录偏移量(这个数字的位置),然后排列剩下的数字,完成后根据偏移量插入之前定位的数字。当只剩一个数字未确定时(只有一种排列)开始层层回溯直到最终结果。
    关键之处在于锁和偏移量的更改要想清楚才能保证回溯不会出错。
  2. 动态规划
    与方法1异途同归,对于上一次获取到的所有排列,插入新的元素,新形成的排列数量为原排列数量乘以i(即阶乘i!),其状态转移方程如下:

dp[i][j] = dp[i - 1][j / (i + 1)].insert(dp[i - 1][j / (i + 1)].begin() + j % (i + 1), nums[count - i - 1]);

  • 其中dp[i]表示新的排列集合,dp[i-1]表示上一次的排列集合,代码实现时分别用dp_next和dp_prev表示,j/(i+1)是选择插入对象,因为对一个排列插入新元素共有i+1种可能性,j%(i+1)是插入新元素的偏移量。
  1. 做完之后看了下discuss,发现自己没有很好地利用"distinct"这个条件,貌似还有个Permutations II是允许包含重复元素的输入来着,emmm,但是不觉得利用distinct的解法更好因此没有再写一个针对它的实现。

53. Maximum Subarray

从左到右遍历数组求和:
1.如果第i个元素前的和小于0,那么从该元素重新开始求和(否则不是加上前面的和反倒又变小了么,以防越过最大子数组左界);
2.如果本次求和的结果大于上次保存的最大子数组和,则更新后者为当前求和结果(防止越过最大子数组右界的情况)。
这是O(n)的解决方案,不过我一开始并没有意识到这个方法本质上其实是动态规划,根据动态规划的思想重新解释的话,步骤(1.)就是其状态转移方程

sum(vec,i) = vec[i] + (sum(vec,i-1) > 0 ? sum(vec,i-1) : 0)

而这只能不断更新确定子数组左界,有可能会越过右界,这时结果是不可靠的,例如[1,1,-3,0]这种情况,其最大子数组为[1,1],但当遍历到-3时,sum[i-1]=2而vec[i]=-3,导致sum[i]=-1,越过右界vec[1]=1,因此需要步骤(2.)来防止这种情况的发生,即对比上次求和结果与本次求和结果,如果变小了,那么有可能越过右界,不取其值。
and WHY using divide and conquer approach ?我并不认为分治法更subtle,不但麻烦且效率低。

66. Plus One

比较简单,模拟加法进位而且是特化的只+1版本,需要注意处理最高位进位的情况。

69. Sqrt(x)

求平方根,可以用二分法求也可以用牛顿法求。二分法不提,牛顿迭代法注意退出条件和整形溢出,另外整形相除的精度损失在计算顺序不同的情况下可能导致WA:

牛顿迭代法公式:xn+1=xn+f'(xn)/f(xn);

ret = (ret + x / ret) / 2;// AC 减少除法造成的精度损失
ret = ret / 2 + x / (ret * 2);// WA

70. Climbing Stairs

到达第n级台阶的方式有两种:从n-1阶跨1阶或从n-2阶跨2阶,因此dp[n]=dp[n-1]+dp[n-2]。可以用动态规划做也可以作为斐波那契数列做,但是暴力递归会导致TLE。

88. Merge Sorted Array

给定两个有序数组nums1和nums2,合并nums1的前m个和nums2的前n个元素到nums1中,nums1的长度不小于m+n(注意此处:需要抹除合并后多于m+n的部分,因为输出的结果是nums1)。
个人有两种解法,第一种直接把nums2插入到nums1的第m个元素后面,擦除多余部分然后对nums1排序可得结果;第二种遍历nums1的前m个和nums2的前n个元素,对比大小按顺序插入到nums1中然后擦除多余部分,需要注意的是nums1的合法长度会随插入新元素数量增长(即循环条件之一应为i1<m+i2),若nums2有剩下的元素(说明m=0或剩下元素都大于nums1[m-1])则直接插入到nums1中。
讨论区有另外一种解法倒序遍历,是第二种的逆向思维,不用考虑i1<m+i2这个细节,只要nums2中的n个合法元素均已按正确的顺序替换到nums1中即可得到正确结果(剩余的nums1合法元素本来就是有序的)。核心代码:

while (i2 > -1) nums1[i--] = i1 > -1 && nums1[i1] > nums2[i2] ? nums1[i1--] : nums2[i2--];

94. Binary Tree Inorder Traversal

二叉树中序遍历,递归方法自然是第一选择,但是要求使用迭代且空间复杂度为O(1),那么可以选择莫里斯遍历(Morris Traversal):
二叉树遍历的主要问题在于当到达叶子节点时如何返回对应的父节点,而该方法的解决方法是通过额外的时间消耗和一个辅助指针,来将父节点对应的需要返回到它的叶子节点的空右子节点指针指向它(相当于构造了一个环),这样,当遍历到叶子节点需要返回时便可以通过该指针回到父节点继续下一步操作。
核心步骤如下:

  • 判断当前节点是否有左子树,如果没有,那么获取当前节点值(中序遍历);
  • 如果有左子树,那么把辅助指针指向左子树,并循环右移直到叶子节点;
    • 如果叶子节点为空(开始构造环),那么把叶子节点的右节点指针指向当前节点(需要返回的父节点),构造一个环,然后当前节点左移到左子树根节点(开始遍历左子树);
    • 如果叶子节点右节点指针指向当前节点(已构造环→左子树已遍历完毕),那么重新把其右节点指针置空(恢复原树结构),获取当前节点值,然后把当前节点移到右子树(开始遍历右子树)。

101. Symmetric Tree

判断一个二叉树是否左右对称,问题可以转换为判断根节点的两个子树是否镜像对称,其特点是结点值相同,且左子树的左子树与右子树的右子树镜像对称、左子树的右子树与右子树的左子树镜像对称。
据此思想,递归的实现容易想到,迭代的做法我直接模拟了函数调用栈的方式来实现。

104. Maximum Depth of Binary Tree

二叉树深度优先遍历。

108. Convert Sorted Array to Binary Search Tree

对已排序数组建立平衡二叉树,递归思想,数据结构了解一下。

118. Pascal's Triangle

杨辉三角,就算没有了解的人也很容易发现其规律,每层左右边界均为1,其他数字为上一层对应两个数字之和。其实也是个动态规划问题,作为数组来归纳其状态转移方程就是

triangle[i][j] = triangle[i - 1][j - 1] + triangle[i - 1][j]

121. Best Time to Buy and Sell Stock

维持一个最小买入价格和当前卖出利润来计算最大利润。注意此题不可以用双层循环,会导致TLE。

122. Best Time to Buy and Sell Stock II

只有一股股票,在知晓给定天数每天价格的前提下获取最大利润,可以将其买卖多次但因为只有一股所以不可以买入复数股再卖掉。说实话感觉这题没什么意思,还不如13题的罗马数字转换。

125. Valid Palindrome

判断回文字符串,但是要求大小写不敏感并且只关心字母和数字,逻辑比较清晰,只判断在az|AZ|0~9间的字符并把小写字符转换为大写字符即可。实现没有用库函数,用库函数判断是否阿尔法字符和进行大小写转换比较简单清晰一些。

136. Single Number

异或的用法很亮眼,坦白地说我没想起来,很惭愧,位运算用到的比较少。
对本题来说,因为异或运算是满足交换律的,因此所有出现两次的数字最终异或结果为0,可以得出唯一一个仅出现一次的single number。

141. Linked List Cycle

判断一个链表是否有环:
如果有环,那么必然有一个节点指向前面的某个节点,基于此想法可以用hash解决,但空间复杂度是O(n);
另外一种很妙的方案,是类比两个人在闭环跑道跑步,如果两人速度不同则必然会相遇,相似地,维持两个指针,一个每次“跑两步”(fast=fast->next->next),另一个每次“跑一步”(slow=slow->next)。如此当有环时两个指针必然会有重叠的情况,无环时指针最终会到达“终点”(null),退出循环。

149. Max Points on a Line

这道题还是比较麻烦的(在LeetCode上AC率15.2%倒数第三),一开始的基本思路是先获取所有构成的不重复直线,然后对每条直线遍历所有的点计算线上点数,但这样有三个问题,一是“不重复”的处理是很笨重,二是要处理大数相乘可能导致的int溢出,三是要处理int除法的精度损失。
后来选择了另一种处理方式,忽略问题一避免问题二,着重处理问题三,核心思想是对于一个已确定的点,只要其他的点与该点构成直线的斜率相同,那么便都在同一直线上(直线的点斜式思想)。步骤如下:

  1. 先选择一个锚点,建立一个std::map,键为斜率,值为以该斜率和锚点确定的直线上点的数量;
  2. 然后遍历其他的点计算与锚点的斜率,斜率要用到除法,为了防止精度损失,这里采用先约分然后std::pair<int,int>存储约分后除数和被除数的方式来转换,但需要注意两种特殊情况:
    sp1. 对于重复点(锚点本身也算是一个重复的点)的数量进行累加,暂称重复数量;
    sp2. 对于斜率不存在的情况,通过std::pair的一对int均置为0来区分为单独一组(除数不可能为0);
  3. 遍历完毕后获取该锚点的map value最大值,并加上重复数量,得到本轮的同一直线上最多点的数量,然后与上一轮的值比较取大者,回步骤1重复直到锚点遍历完毕即可得到结果。

155. Min Stack

实现一个可以获取最小值的栈,要求压出栈、获取栈顶和最小元素的操作时间复杂度都是O(1)。
因为是栈,所以出栈元素的顺序是固定的(先入后出),那么可以维持一个容器保存栈中最小值更新的记录,我这里用了一个数组,如果压/出栈时最小值更新了,那么把更新的最小值放入/取出数组,这样无论何时该数组的最后一个元素都是当前最小值。关键代码:

if (mins_.empty() || x <= mins_.back()) mins_.push_back(x);// 压栈时的判断
if (values_.back() == mins_.back()) mins_.pop_back();// 出栈时的判断

160. Intersection of Two Linked Lists

emmm这道题...我想到了双指针“跑步”但是跑偏了→_→
要求找出两个无环单链表的交叉点,时间复杂度O(n),空间复杂度O(1),不能改变原链表结构。假如把两个链表拼接起来,那么如果有交叉点则必然在同一时间达到这个交叉点,如下图所示:


two pointers

169. Majority Element

主要元素的数量多于一半的情况下意味着最多数量者即为解,且不同元素的数量必然少于相同元素数量。

171. Excel Sheet Column Number

可能是我英文水平不够,读了好几遍才理解这题意思,事实上就是完成26进制到10进制的转换。

172. Factorial Trailing Zeroes

这道题有点像脑筋急转弯...?好吧是我数字敏感性不够#_#
题目是求出n!结果中数位0的个数,但要求时间复杂度为对数阶。其中原理是结果中的每个0都必然来自于x10,而10可以分解为2x5,由于因数2的数量多于因数5,因此我们只需要统计出n!的因数中5的数量即为结果中数位0的数量,至于求因数5的数量可以使n对5辗转相除,累加每次相除的结果(e.g. 26/5=5,5/5=1,5+1=6,26的阶乘可以分解出6个因数5,则其阶乘结果中含6个0数位):while ((n /= 5) > 0) sum += n;

189. Rotate Array

获取数组循环右移n步的结果。
根据右移步数和数组长度可以知道每个数组元素的最终位置,通过右移步数对数组长度求余,得到原本数组尾部移动到数组头部的元素数量,然后把这些元素插入头部再清除尾部多余元素。

190. Reverse Bits

位运算题,每次完成1bit的位置反转共32bit,要先想清楚运算逻辑。

191. Number of 1 Bits

位运算题,因为是求二进制位为1的数量,因此把n循环右移并与1做与(&)运算直到n为0即可(右移高位补0,为0时说明剩下的二进制位中已经没有1了)。

198. House Robber

最先想到的还是递归,不过提交之后会TLE,没办法还是写迭代吧,为了不超时,又是一个动态规划的做法。
因为不能抢劫两栋相邻房屋,因此抢劫到第n栋房屋时的最大收获要么是前面n-1栋的最大收获,要么是前面n-2栋的最大收获加上第n栋的收获,状态转移方程:

dp[i] = max(dp[i - 1], nums[i - 1] + dp[i - 2])

202. Happy Number

对各数位的平方循环求和,如果结果为1返回true,结果发生了循环返回false(哈希确认),否则继续下一次数位平方求和。

204. Count Primes

求小于n的素数数量,筛法实现,假设所有(1,n)内的所有自然数都是素数,从2开始,如果是素数那么它的所有倍数都是非素数,遍历完成后可以筛出所有素数。

206. Reverse Linked List

单链表反转的迭代和递归实现。

217. Contains Duplicate

哈希或者set集合。

234. Palindrome Linked List

判断单链表是否回文。考虑O(n)时间复杂度和O(1)空间复杂度,因为回文链表的后半部分必然是前半部分的反转,有以下解决方案:

  1. 先通过双指针方式取得链表的后半部分([1,2,3,2,1]->[2,1],[1,2,2,1]->[2,1]);
  2. 反转后半部分,然后同时遍历链表前半部分和反转的后半部分,如果全部匹配那么就是回文链表。

237. Delete Node in a Linked List

这道题很容易,把指向当前节点的指针指向下一节点即可,但是需要注意不要忘记内存管理,记得释放。

238. Product of Array Except Self

给定数组nums,对于其中的每一个元素nums[i],求出除nums[i]之外所有元素的乘积。
简单来说,返回数组ret中:

ret[i] = nums[0]*nums[1]*...*nums[i-1]*nums[i+1]*...*nums[n-1];
ret[i] = (nums[0]*nums[1]*...*nums[i-1])  *  (nums[i+1]*...*nums[n-1]);
ret[i] = 1 * (nums[0]*nums[1]*...*nums[i-1])  *  (nums[i+1]*...*nums[n-1]);// 1*front*back

可以把前面和后面的部分分别视为两个因子front和back,遍历nums[i],分别从头/尾部迭代计算front/back,并分别在头/尾部与对应的ret[i]/ret[n-1-i]相乘,遍历完成后即得结果。

242. Valid Anagram

两种方法:排序后比较或哈希思想。

268. Missing Number

要满足时间复杂度O(n)和空间复杂度O(1),第一时间想起来的是求n个数的和然后减去实际和的方式(高斯公式),另外LeetCode上还有一种解法是用异或也很棒,再次用到了异或的交换律。

283. Move Zeroes

可以顺序遍历,把第n个发现的非零数与第n个数(0)交换,也可以逆序遍历,把第n个发现的0与第n个非零数交换,为了减少交换次数,可以在遍历次数等于n时不做交换。

326. Power of Three

一种迭代求解,一种换底公式,注意要以10为底,否则会有精度问题。LeetCode给出还有另外两种解法,进制转换和用满足条件的最大int对n求余。
这道题没什么意义,踩。

344.Reverse String

回字的四种写法。

347. Top K Frequent Elements

获取给定集合中出现频率最高的k个元素,要求时间复杂度低于O(nlogn),很经典的题目。

  • 首先要统计集合中所有元素的出现频率,哈希表是第一选择;
  • 其次要根据频率进行排序,且不能丢掉与频率关联的元素值,看到O(nlogn)的时间复杂度限制,可以知道普通的比较排序必然是不满足要求的,因此可以选择时间复杂度为O(n)的桶排序,也可以使用优化过的原本为O(nlogn)时间复杂度的比较排序比如堆排序快速排序,本题目我实现了包含桶排序、堆排序(最大堆、最小堆)和快速排序的四种方案,堆排序的优化在于减少堆元素数量(O(nlogk)或O(nlog(n-k)),快速排序直接调用了C++ functional库的nth_element,属于部分快速排序。
    皆满足题目要求,受益匪浅,之前还不晓得有个nth_element来着。
  • 关于桶排序:由于桶本身是有序的,因此桶排序不需要进行比较,用可能大量冗余的空间换取了时间,这是它突破比较排序时间复杂度下线O(nlogn)的原因。
  • 关于堆排序:堆的本质是一棵完全二叉树,且具有每个节点必定大于(最大堆)/小于(最小堆)其子节点的性质。std::priority_queue默认是最大堆,容器采用vector<T>,比较方法为less<T>,可以自定义比较方法(std提供的greater<T>可以用于最小堆),堆排序建堆的时间复杂度为O(n),而调堆的时间复杂度为O(logn),原因在于建堆是自底向上而调堆是自顶向下。
  • 关于快速排序:快速排序的时间复杂度是不稳定的,受到原元素顺序的限制,在随机度较高的情况下它优于堆排序,因为堆排序的n是堆元素数量远大于快速排序的n,但恶化的快排(O(n2))不如堆排。

350. Intersection of Two Arrays II

写了三种,哈希、遍历和排序,其中排序不适用于不改变交集元素出现顺序的要求(For follow up)。
关于Follow up第三条,如果两个数据量都是海量的,可以采取外排序方式然后对排序后的数组求交集(方法三)。

371. Sum of Two Integers

每次相加分为两步,先计算无进位再计算进位,用了递归思想,逻辑比较清晰,因为ban掉了+-运算符,所以很容易想起来如何用位运算做。

378. Kth Smallest Element in a Sorted Matrix

给定一个横向和纵向都递增的n*n矩阵,找出其中第k小的元素。
实现了两种方法,堆排和快排,其中快排没有用std的算法权当练手了,可以参照347题,那道题比这个复杂一些,我给出了较为详细的解释。
另外还有一种据说时间复杂度是O(n)的特化算法但是我没仔细看,后续有时间了再学习一下。

384. Shuffle an Array

这道题的意义在于去了解Fisher-Yates洗牌算法。

Fisher-Yates原理:
对于给定的一个长度为n原始序列,每次(第i次,i>=0)随机选择原始序列前n-i个元素中的一个与第n-i个元素交换位置,即从后往前每次确定一个元素,直到全部确定完成shuffle。
只要随机选择元素的时候是真随机,那么shuffle结果也是真随机的。

387. First Unique Character in a String

可以想到两种方案,一是哈希表保存字符计数信息,然后获得单字符index,二是两次遍历查找是否重复。

412. Fizz Buzz

vector初始化以便使用下标。

454. 4Sum II

暴力求解的时间复杂度过高O(n4),可以二分法解决,4个数组两两一组求和然后判断是否互补即可,复杂度为O(n2)。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容