动态规划题总结

最长递增子序列

给定一个无序的整数数组,找到其中最长上升子序列的长度。
示例:
输入: [10,9,2,5,3,7,101,18]
输出: 4
解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4。

思路
序列的初始值都是1,那么如果当前值i比j(0<=j<i)要大,j与之前数组成的递增子序列就可以+1了,当然要和目前已经更新的最大值比较,这样经过n^2次比较可以求出最长递增子序列的dp[]数组
找出这个序列的方法也很简单,先找到最大值dp[i]和对应的index,然后反向遍历,如果dp[j] = dp[i] - 1 并且 arr[j] < arr[i], 那么这个数就是递增子序列中的一个

//最优解:
public static int LongestSubString(int arr[])
    {
        int len=0;
        if(arr==null||arr.length==0)
            return 0;
        int dp[]=new int[arr.length];
        dp[0]=1;
        //dp[i] 表示到i为止是最长递增子序列的长度
        for(int i=1;i<arr.length;i++)
        {
            dp[i]=1;
            for(int j=0;j<i;j++)
            {
                if(arr[i]>arr[j])
                {
                //求dp[i]时遍历,dp[0...i-1],找出arr[j]<arr[i]小且dp[j]是最大的
                //dp[i]=dp[j]+1;
                    dp[i]=Math.max(dp[i],dp[j]+1);
                }
            }
        }   
        for(int i=0;i<arr.length;i++)
        {
            len=Math.max(dp[i],len);
        }
     return len;

    //最优值,求出dp[i]之后要求出递增子序列[10,22,33,41,60,80]
    //先找到最大dp[i],从后往前,如果dp[i]==dp[j]+1,且arr[i]>arr[j],则可知arr[j]是子序列中
    //arr[i]前面的数.

    public  generateLIS(int arr[],int dp[])
    {
        int k=0;
        int index=0;
        int len=0;
        for(int i=0;i<arr.length;i++)
        {
            if(dp[i]>len)
            {
                len=dp[i];
                index=i;
                //找到递增子序列中的最后一个元素[10,22,33,41,60,80]中的80,
            }
        }
        int subArr[]=new int[len];
        subArr[k++]=arr[index]; 
        for(int j=index-1;j>=0;j--)
        {
            if((dp[index]==dp[j]+1)&&(arr[index]>arr[j]))
            {
                //从后向前,将属于递增子序列的元素加入到subArr中。
                subArr[k++]=arr[j];
                index=j;
            }
        }
        for(int j=subArr.length-1;j>=0;j--)
        {
            System.out.print(subArr[j]+" ");
        }

    }
--------------------- 
作者:HankingHu 
来源:CSDN 
原文:https://blog.csdn.net/u013309870/article/details/62037674 
版权声明:本文为博主原创文章,转载请附上博文链接!

最长公共子序列

题目:如果字符串一的所有字符按其在字符串中的顺序出现在另外一个字符串二中,
则字符串一称之为字符串二的子串。

image.png

思路
假如S1的最后一个元素 与 S2的最后一个元素相等,那么S1和S2的LCS就等于 {S1减去最后一个元素} 与 {S2减去最后一个元素} 的 LCS 再加上 S1和S2相等的最后一个元素。
假如S1的最后一个元素 与 S2的最后一个元素不等(本例子就是属于这种情况),那么S1和S2的LCS就等于 : {S1减去最后一个元素} 与 S2 的LCS, {S2减去最后一个元素} 与 S1 的LCS 中的最大的那个序列。


公式
public static String LCS_caculate(String s1,String s2){
        int size1=s1.length();
        int size2=s2.length();
        int chess[][]=new int[s1.length()+1][s2.length()+1];
        for(int i=1;i<=size1;i++){//根据上面提到的公式计算矩阵
            for(int j=1;j<=size2;j++){
                if (s1.charAt(i-1)==s2.charAt(j-1)) {
                    chess[i][j]=chess[i-1][j-1]+1;
                }else {
                    chess[i][j]=max(chess[i][j-1],chess[i-1][j]);
                }
            }
        }
        int i=size1;
        int j=size2;
        StringBuffer sb=new StringBuffer();
        while((i!=0)&&(j!=0)){//利用上面得到的矩阵计算子序列,从最右下角往左上走
            if (s1.charAt(i-1)==s2.charAt(j-1)) {
                sb.append(s1.charAt(i-1));//相同时即为相同的子串
                i--;
                j--;
            }else {
                if (chess[i][j-1]>chess[i-1][j]) {
                    j--;
                }else {
                    i--;
                }
            }
        }
        System.out.println((double)sb.length()/s2.length()+","+(double)sb.length()/s1.length());
        return sb.reverse().toString();//记得反转
    }
--------------------- 
作者:Bryan__ 
来源:CSDN 
原文:https://blog.csdn.net/Bryan__/article/details/51927537 
版权声明:本文为博主原创文章,转载请附上博文链接!

最长公共子串

问题:有两个字符串str和str2,求出两个字符串中最长公共子串长度。
比如:str=acbcbcef,str2=abcbced,则str和str2的最长公共子串为bcbce,最长公共子串长度为5。

思路
跟最长公共子串差不多,只是要求字符串是连续的,所以每次相等时对dp[i-1][j-1]+1,如果不等就直接为0了

/**
     * 获取两个字符串最长公共子串长度
     * @param str   第一个字符串
     * @param str2  第二个字符串
     * @return  如果存在则返回最长公共子串长度,否则返回0
     */
    public static int getLCSLength2(String str, String str2){
        char[] ary = str.toCharArray();
        char[] ary2 = str2.toCharArray();
        
        int[][] temp = new int[ary.length][ary2.length];    //声明一个二维数组,存储最长公共子串长度
        int length = 0; //最长公共子串长度
        
        for(int i = 0; i < ary2.length; i++){   //初始化二维矩阵中的第一行
            temp[0][i] = (ary[0] == ary2[i]) ? 1 : 0;
        }
        
        for(int j = 1; j < ary.length; j++){    //初始化二维矩阵中的第一列
            temp[j][0] = (ary2[0] == ary[j]) ? 1 : 0;
        }
        
        for (int i = 1; i < ary.length; i++) {
            for (int j = 1; j < ary2.length; j++) {
                if(ary[i] == ary2[j]){
                    temp[i][j] = temp[i-1][j-1] + 1;
                    
                    if(temp[i][j] > length){    //当前元素值大于最大公共子串长度
                        length = temp[i][j];
                    }
                }else{
                    temp[i][j] = 0;
                }
            }
        }
        return length;
    }
--------------------- 
作者:banbanaoxiang 
来源:CSDN 
原文:https://blog.csdn.net/u010397369/article/details/38979077 
版权声明:本文为博主原创文章,转载请附上博文链接!

最大子序列和

问题: 给定(可能有负数)整数序列A1, A2, A3..., An, 求这个序列中子序列和的最大值。(为方便起见,如果所有整数均为负数,则最大子序列和为0)。例如:输入整数序列: -2, 11, 8, -4, -1, 16, 5, 0,则输出答案为35,即从A2~A6。

思路: 只要子序列和不小于0就有可能是最大子序列和的一部分,但是如果小于0了就肯定不是了

public static int maxSubsequenceSum(int[] a) {
    int maxSum = 0, thisSum = 0;;
    for(int i=0; i<a.length; i++) {
        thisSum += a[i];
        if(thisSum > maxSum)
            maxSum = thisSum;
        else if(thisSum < 0)
            thisSum = 0;
    }
    return maxSum;
}

数组中的最长连续序列

题目:找出无序数组中的最长连续序列的长度:例如数组[ 1 , 23 , 2 , 300 , 3 , 9 ,4 , 5 , 90 ],最长连续序列为:1,2,3,4,5,因此返回长度为 5。

分割回文串

给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。

返回 s 所有可能的分割方案。

示例:

输入: "aab"
输出:
[
["aa","b"],
["a","a","b"]
]

思路: 回溯法,每次去从当前点开始扩展出去,如果是回文就在当前的基础上再进行下一次的查找

class Solution {
    List<List<String>> resultList;
    ArrayList<String> current;
 
    public List<List<String>> partition(String s) {
        resultList = new ArrayList<>();
        current = new ArrayList<String>();
        findPalindrome(s, 0);
        return resultList;
    }
 
    /**
     * 主要思路是回溯
     * @param str
     * @param left
     */
    private void findPalindrome(String str, int left) {
        //回溯返回条件,left指针已到最后,也就是回溯到底了
        if (current.size() > 0 && left >= str.length()) {
            ArrayList<String> tempList = (ArrayList<String>) current.clone();
            resultList.add(tempList);
        }
        for (int right = left; right < str.length(); right++) {
            //不是回文的话,直接right++;
            if (isPalindrome(str, left, right)) {
                //添加回文
                if (left == right) {
                    current.add(Character.toString(str.charAt(left)));
                }else{
                    current.add(str.substring(left, right +1));
                }
                //进行回溯
                findPalindrome(str, right + 1);
                //移除刚刚添加的元素,也就是回到之前的状态,以便走其他分支
                current.remove(current.size() - 1);
            }
        }
 
    }
 
    public boolean isPalindrome(String str, int left, int right) {
        if (left == right) {
            return true;
        }
        while (left < right) {
            if (str.charAt(left) != str.charAt(right)) {
                return false;
            }
            left++;
            right--;
        }
        return true;
    }
}

回文最少分割数

给定一个字符串s,将s分割成一些子串,使每个子串都是回文。
返回s符合要求的的最少分割次数。

思路:第一步,创建一个二维数组,假设为b,其中b[i][j],表示的是如果i~j范围的字符串是回文字符串的话,b[i][j]为true,反之为false。这里就是这道题比较难的部分
  这里用图片来辅助解释一下

示意图

例如上面的图片,其中i在[1,s.length()]区间里面,至于为什么在这个区间里面,待会代码中解释;j再[0, s.length() - i + 1)区间里面;k是由i,j计算出来的。
  从图中我们可以得出的是,i表示[i,k]的字符串的中心,i,表示子串的两端,我们可以得出:如果s.charAr(j) == s.charAt(k)和b[j +1][k - 1]为true的话,b[i][k]肯定为true。
  第二步,再创建一个以维数组,假设为dp,其中dp[i],表示切割0~i范围的字符串的最小次数。动态规划方程:dp[i] = Math.min(dp[i], dp[j] + 1);
作者:琼珶和予
链接:https://www.jianshu.com/p/188780c84d78
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

    public int minCut(String s) {
        boolean[][] b = new boolean[s.length()][s.length()];
        for (int i = 1; i <= s.length(); i++) {
            //j表示以i为中心的子字符串左侧
            //s.length() - i + 1,计算的是i的右侧还有几个字符
            //所以j在[0, s.length() - i + 1)
            //这里便能解释为什么i必须从1开始,如果从0开始的话,0是没有左侧的
            for (int j = 0; j < s.length() - i + 1; j++) {
                //以i为中心,与j对应的右侧位置k
                int k = j + i - 1;
                if (i == 1) {
                    b[j][k] = true;
                } else {
                    if (s.charAt(j) == s.charAt(k) && (j == k - 1 || b[j + 1][k - 1]))
                        b[j][k] = true;
                }
            }
        }
        int[] dp = new int[s.length()];
        Arrays.fill(dp, Integer.MAX_VALUE);
        for (int i = 0; i < s.length(); i++) {
            if (b[0][i]) {
                dp[i] = 0;
            }
            for (int j = 0; j < i; j++) {
                if (b[j + 1][i])
                    dp[i] = Math.min(dp[i], dp[j] + 1);
            }
        }
        return dp[s.length() - 1];
    }

至少有K个重复字符的最长子串

找到给定字符串(由小写字符组成)中的最长子串 T , 要求 T 中的每一字符出现次数都不少于 k 。输出 T 的长度。
输入:
s = "ababbc", k = 2
输出:
5
最长子串为 "ababb" ,其中 'a' 重复了 2 次, 'b' 重复了 3 次。

思路:记录每个字符出现的次数,把出现次数小于k次的字符存放在splitSet中,如果没有,说明子串所有字符都出现大于k次,可以直接返回。否则就根据分割点分割然后进行下次检查

public int longestSubstring(String s, int k) {
    HashMap<Character, Integer> counter = new HashMap<Character, Integer>();
  
    for(int i=0; i<s.length(); i++){
  
        char c = s.charAt(i);
        if(counter.containsKey(c)){
            counter.put(c, counter.get(c)+1);
        }else{
            counter.put(c, 1);
        }
  
    }
  
    HashSet<Character> splitSet = new HashSet<Character>();
    for(char c: counter.keySet()){
        if(counter.get(c)<k){
            splitSet.add(c);
        }
    }
  
    if(splitSet.isEmpty()){
        return s.length();
    }
  
    int max = 0;
    int i=0, j=0;
    while(j<s.length()){
        char c = s.charAt(j);
        if(splitSet.contains(c)){
            if(j!=i){
                max = Math.max(max, longestSubstring(s.substring(i, j), k));
            }
            i=j+1;
        }
        j++;
    }
  
    if(i!=j)
         max = Math.max(max, longestSubstring(s.substring(i, j), k));
  
    return max;
}  

三角形最小路径和

思路: 从下往上算出每个节点到父节点的最小路径,然后循环向上即可,顶点就是最大值
申请n个空间minNums[n],初始化minNums[n]为数据triangle[][]的最后一行。最后一行的数字到最底层的最小路径和就是他们自己本身。
从倒数第二行开始往上(row),从左向右(col)循环计算并更新minNums的值,minNums[col]=min(minNums[col], minNums[col+1]) + triangle[row][col], 最后minNums[0]就是我们要的答案。
作者:Orange橘子洲头
来源:CSDN
原文:https://blog.csdn.net/smile_watermelon/article/details/46741303
版权声明:本文为博主原创文章,转载请附上博文链接!

public int minimumTotal(List<List<Integer>> triangle) {
    int[] A = new int[triangle.size()+1];
    for(int i=triangle.size()-1;i>=0;i--){
        for(int j=0;j<triangle.get(i).size();j++){
            A[j] = Math.min(A[j],A[j+1])+triangle.get(i).get(j);
        }
    }
    return A[0];
}

二叉树中的最大路径和

给出一棵二叉树,寻找一条路径使其路径和最大,路径可以在任一节点中开始和结束(路径和为两个节点之间所在路径上的节点权值之和)

思路: 与三角形的最小路径和相似,只是二叉树只能从顶向下,这样可以算出每个孩子的路径然后递归求到最大路径和,需要将负数的路径减枝

class Solution {
public:
    int maxPathSum(TreeNode* root) {
        int res = INT_MIN;
        helper(root, res);
        return res;
    }
    int helper(TreeNode* node, int& res) {
        if (!node) return 0;
        int left = max(helper(node->left, res), 0);
        int right = max(helper(node->right, res), 0);
        res = max(res, left + right + node->val);
        return max(left, right) + node->val;
    }
};

单词拆分

Given a string s and a dictionary of words dict, determine if s can be segmented into a space-separated sequence of one or more dictionary words.

For example, given
s = “leetcode”,
dict = [“leet”, “code”].

Return true because “leetcode” can be segmented as “leet code”.

思路: 将问题拆分成更小的子问题。用dp[i]表示0到i的子字符串是否可以拆分成满足条件的单词,在计算dp[i]的时候,我们已经知道dp[0],dp[1],…,dp[i-1],如果以i为结尾的ji子串是满足条件的,并且0j的子串也是在字典中的,那么dp[i]就是true。
用公式表示就是:
∪res[j]&&s.substring[j,i+1]∈dict

   public boolean wordBreak(String s, Set<String> wordDict) {
        if(s==null || s.length() == 0){
            return false;
        }
        boolean[] res = new boolean[s.length()+1];
        res[0] = true;
        for(int i=0;i<s.length();i++){
            StringBuilder str = new StringBuilder(s.substring(0, i+1));
            for(int j=0;j<=i;j++){
                if(res[j] && wordDict.contains(str.toString())){
                    res[i+1] = true; 
                    break;
                }
                str.deleteCharAt(0);
            }
        }

        return res[s.length()];
    }
--------------------- 
作者:xddc 
来源:CSDN 
原文:https://blog.csdn.net/congduan/article/details/45245975 
版权声明:本文为博主原创文章,转载请附上博文链接!

单词拆分2

给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,在字符串中增加空格来构建一个句子,使得句子中所有的单词都在词典中。返回所有这些可能的句子。

思路: 先计算是否可拆分,然后通过判断进行回溯,这样其实需要的循环就很少了

public List<String> wordBreak(String s, Set<String> wordDict) {
    ArrayList<String> [] pos = new ArrayList[s.length()+1];
    pos[0]=new ArrayList<String>();
  
    for(int i=0; i<s.length(); i++){
        if(pos[i]!=null){
            for(int j=i+1; j<=s.length(); j++){
                String sub = s.substring(i,j);
                if(wordDict.contains(sub)){
                    if(pos[j]==null){
                        ArrayList<String> list = new ArrayList<String>();
                        list.add(sub);
                        pos[j]=list;
                    }else{
                        pos[j].add(sub);
                    }
  
                }
            }
        }
    }
  
    if(pos[s.length()]==null){
        return new ArrayList<String>();
    }else{
        ArrayList<String> result = new ArrayList<String>();
        dfs(pos, result, "", s.length());
        return result;
    }
}
  
public void dfs(ArrayList<String> [] pos, ArrayList<String> result, String curr, int i){
    if(i==0){
        result.add(curr.trim());
        return;
    }
  
    for(String s: pos[i]){
        String combined = s + " "+ curr;
        dfs(pos, result, combined, i-s.length());
    }
} 

完全平方数

给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, …)使得它们的和等于 n。你需要让组成和的完全平方数的个数最少。

思路:广度优先+队列,每次都把可以减少的数减去,然后进行下次递归,当等于0时返回step

class Solution {
    public int numSquares(int n) {
        //Queue<Integer> queue = new PriorityQueue<>();
        //知识点链表赋值给队列接口,也可以如上使用优先队列
        //对这个有疑问可参考:https://stackoverflow.com/questions/21727873/queueinteger-q-new-linkedlistinteger
        Queue<Integer> queue = new LinkedList<>();
        Set<Integer> set = new HashSet<>();
        int step = 0;
        queue.offer(n);
        while (!queue.isEmpty()) {
            int size = queue.size();
            step++;
            for (int i = 0; i < size; i++) {
                int curr = queue.poll();
                if (!set.add(curr)) {
                    continue;
                }
                for (int j = 1; j <= Math.sqrt(curr); j++) {
                    int next = curr - j * j;
                    if (next == 0) {
                        return step;
                    }
                    queue.offer(next);
                }
            }
        }
        return 0;
    }
}

零钱兑换

给定不同面额的硬币(coins)和一个总金额(amount)。写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合方式能组成总金额,返回-1。
示例 1:
coins = [1, 2, 5], amount = 11
return 3 (11 = 5 + 5 + 1)

示例 2:
coins = [2], amount = 3
return -1.

注意:
你可以认为每种硬币的数量是无限的。

思路:如果能换就是dp[i-coins[j]] +1, 不能换就是默认值,取小的那个

class Solution {
public:
    int coinChange(vector<int>& coins, int amount) {
        vector<int> dp(amount+1,amount+1);
        dp[0]=0;
        int n=coins.size();
        if(n==0||amount==0) return 0;
        sort(coins.begin(),coins.end());
        for(int i=1;i<=amount;i++){
            for(int j=0;j<coins.size()&&coins[j]<=i;j++){
                dp[i]=min(dp[i],dp[i-coins[j]]+1);
            }
        }
        if(dp[amount]==amount+1) return -1;
        else return dp[amount];
    }
};
--------------------- 
作者:沧海漂游_ 
来源:CSDN 
原文:https://blog.csdn.net/lv1224/article/details/79879032 
版权声明:本文为博主原创文章,转载请附上博文链接!

买卖股票的时机-1

给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。

如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润。

注意你不能在买入股票前卖出股票。

示例 1:

输入: [7,1,5,3,6,4]
输出: 5
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格。
示例 2:

输入: [7,6,4,3,1]
输出: 0
解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。

思路:维护一个min数组来记录之前的最小值,然后用当前值减去最小值即可,更新max

class Solution {
    public int maxProfit(int[] prices) {
        if(prices.length <= 1) {
            return 0;
        }
        int[] min = new int[prices.length];
        min[0] = prices[0];
        int maxProfit = 0;
        for(int i=1;i < prices.length;i++){
            min[i] = prices[i] < min[i-1]? prices[i] : min[i-1];
            maxProfit = maxProfit < prices[i] - min[i]?prices[i] - min[i]:maxProfit;
        }
        return maxProfit;
    }
}

买卖股票的时机-2

给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。

设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。

注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

思路:因为可以当日买卖,所以只要有利润就可以买卖

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