03-1

1.固定数组实现栈

定义一个辅助空间index,一开始指向数组0的位置,所指位置即入栈或者出栈的位置。每次一个元素要入栈,则将该元素放进index所指向的位置,再将index+1;要出栈一个元素,则将index-1,将此时index上的元素取出。遇到边界则抛异常。

 public static class ArrayStack{
        public int[] arr;
        public Integer index;
        ArrayStack(int initSize){
            if (initSize<0){
                throw new IllegalArgumentException("The init size is less than 0");
            }
            arr=new int[initSize];
            index=0;
        }
        public Integer peek(){
            if(index==0){
                return null;
            }
            return arr[index-1];
        }
        public void push(int obj){
            if(index==arr.length){
                throw new ArrayIndexOutOfBoundsException("the stack is full");
            }
            arr[index++]=obj;
        }
        public Integer pop(){
            if(index==0){
                throw new ArrayIndexOutOfBoundsException("the stack is empty");
            }
            return arr[--index];
        }
    }

2.固定数组实现队列

定义三个辅助空间start(指向要入的位置),end(指向要出的位置),size。定义size的原因是为了方便解耦,使得start只和size相关,end只和size相关,start和end各走各的没有关系(为了循环使用数组)。start,end一开始都指向数组0的位置。每次一个元素要入队,在size小于数组长度的情况下,将该元素放进start所指向的位置,再判断一下此时start是否为数组最后一个位置,如果是就回到0位置(之前肯定有元素出队了,因为没有出队的话size就会等于数组长度,以上都不会判断),否则则将start+1;要出栈一个元素,在size大于0的情况下,将end所指向的位置的元素取出,再判断一下此时end是否为数组最后一个位置,如果是就回到0位置(之前肯定有元素出队了,因为没有出队的话size就会等于数组长度,以上都不会判断),否则则将end+1。start和end互不影响。以下为实现代码:

package StackAndQyeue;
import java.util.Arrays;
public class Array_To_Stack_Queue {
    public static class ArrayStack{
        public Integer[] arr;
        public Integer size;
        ArrayStack(int initSize){
            if (initSize<0){
                throw new IllegalArgumentException("The init size is less than 0");
            }
            arr=new Integer[initSize];
            size=0;
        }
        //返回栈顶的值
        public Integer peek(){
            if(size==0){
                return null;
            }
            return arr[size-1];
        }
        public void push(int obj){
            if(size==arr.length){
                throw new ArrayIndexOutOfBoundsException("the stack is full");
            }
            arr[size++]=obj;
        }
        public Integer pop(){
            if(size==0){
                throw new ArrayIndexOutOfBoundsException("the stack is empty");
            }
            return arr[--size];
        }

    }
    public static class ArrayQueue{
        public Integer[] arr;
        public Integer size;
        public Integer start;
        public Integer end;
        ArrayQueue(int initSize){
            if (initSize<0){
                throw new IllegalArgumentException("The init size is less than 0");
            }
            arr=new Integer[initSize];
            size=0;
            //start 指着入的位置
            start=0;
            //end 指着出的位置
            end=0;
        }
        public Integer peek(){
            if (size==0){
                throw new ArrayIndexOutOfBoundsException("the queue is empty");
            }
            return arr[end];
        }
        public void push(int obj){
            if(size==arr.length){
                throw new ArrayIndexOutOfBoundsException("the queue is full");
            }
           // 应该都行
            arr[start++]=obj;
            //循环使用数组 到达边界跳到0
            if (start==arr.length){
                start=0;
            }
            size++;
//            arr[start]=obj;
//            start= start==arr.length-1?0:start+1;
//            size++;
        }
        public Integer pop(){
            if (size==0){
                throw new ArrayIndexOutOfBoundsException("the queue is empty");
            }
            if (end==arr.length){
                end=0;
            }
            size--;
            return arr[end++];
//            int tmp=end;
//            //记录一下队顶的元素,然后把该元素变成null
//            Integer top=arr[tmp];
//            arr[tmp]=null;
//            end=end==arr.length-1?0:end+1;
//            return top;
        }
    }

3.仅用队列结构实现栈结构

使用两个队列能够实现一个栈结构。
假设有队列A和队列B。
首先将元素依次入队列A,如果想要出一个元素,把除了最后一个元素其他的元素都入队列B,再将A中剩下的那个元素出队即可。此时B队列可以看成之前的A队列。

 //假设有队列A和队列B。
    //首先将元素依次入队列A,如果想要出一个元素,把除了最后一个元素其他的元素都入队列B,
    // 再将A中的元素出队即可。
    // 此时B队列可以看成之前的A队列。
    public static class TwoQueueStack {
        public Queue<Integer> queue;
        public Queue<Integer> help;
        TwoQueueStack(){
            queue=new LinkedList<Integer>();
            help=new LinkedList<Integer>();
        }
        public void push(int obj) {
            queue.add(obj);
        }

        public Integer pop() {
            if(queue.isEmpty()&&help.isEmpty()){
                throw new RuntimeException("the stack is empty");
            }
            while(queue.size()>1){
                help.add(queue.poll());
            }
            Integer res=queue.poll();
            //交换这两个队列的名字
            swap(queue,help);
            return res;
        }

        private void swap(Queue<Integer> queue, Queue<Integer> help) {
            this.help = queue;
            this.queue=help;
        }

        public Integer peek(){
            if(queue.isEmpty()&&help.isEmpty()){
                throw new RuntimeException("the stack is empty");
            }
            while(queue.size()>1){
                help.add(queue.poll());
            }
            Integer res=queue.peek();
            help.add(res);
            //交换这两个队列的名字
            swap(queue,help);
            return res;
        }

4.仅用栈结构实现队列结构?

使用两个栈能够实现一个队列结构。
假设有栈A和栈B。
首先将元素依次入栈A,每一次元素要出的时候,将A中的所有元素都入栈B,前提是栈B中没有元素。只要满足两个限制即可:1.A栈元素入B栈的时候,一次要全倒完;2.B栈只有在空的情况下才能被倒入元素。何时倒入元素都可以,只要满足上述两个条件。

//假设有栈A和栈B。
    //首先将元素依次入栈A,每一次元素要出的时候,将A中的所有元素都入栈B,前提是栈B中没有元素。
    // 只要满足两个限制即可:1.A栈元素入B栈的时候,一次要全倒完;
    // 2.B栈只有在空的情况下才能被倒入元素。
    // 何时倒入元素都可以,只要满足上述两个条件。
    public static class TwoStackQueue {
        private Stack<Integer> stackPush;
        private Stack<Integer> stackPop;
        TwoStackQueue(){
             stackPush=new Stack<Integer>();
             stackPop=new Stack<Integer>();
        }
        public void push(int obj) {
            stackPush.push(obj);
        }
        public Integer poll() {
            if (stackPop.empty() && stackPush.empty()) {
                throw new RuntimeException("Queue is empty");
            } else if (stackPop.empty()) {
                while (!stackPush.empty()) {
                    stackPop.push(stackPush.pop());
                }
            }
            return stackPop.pop();
        }

        public Integer peek() {
            if (stackPop.empty() && stackPush.empty()) {
                throw new RuntimeException("Queue is empty");
            } else if (stackPop.empty()) {
                while (!stackPush.empty()) {
                    stackPop.push(stackPush.pop());
                }
            }
            return stackPop.peek();
        }
    }

5.实现一个特殊的栈,在实现栈的基本功能的基础上,再实现返回栈中最小元素的操作。

【要求】 1.pop、push、getMin操作的时间复杂度都是O(1)。 2.设计的栈类型可以使用现成的栈结构。
第一种实现方案:
假设有栈stackData和栈stackMin。
栈stackData正常做栈的操作,保存当前栈中的元素,栈stackMin则每次把最小的元素入栈,用于保存每一步的最小值,栈stackData和栈stackMin保持同步。
假设当前数据为newNum,先将其压入stackData。然后判断stackMin是否为空。
如果为空,则newNum也压入stackMin;如果不为空,比较newNum和stackMin的栈顶元素中哪个更小。
如果newNum更小或两者相等,将newNum入DataMin;否则,将stackMin的栈顶元素重复压入stackMin,即在栈顶元素上再压入一个栈顶元素。
出栈时,在stackData中弹出数据;弹出stackMin的栈顶。

 public static class stack1{
        Stack<Integer> stackData;
        Stack<Integer> stackMin;
        //栈A正常做栈的操作,保存当前栈中的元素,
        // 栈B则每次把最小的元素入栈,用于保存每一步的最小值,栈A和栈B保持同步。
        //假设当前数据为newNum,先将其压入stackData。然后判断stackMin是否为空。
        //如果为空,则newNum也压入stackMin;如果不为空,比较newNum和stackMin的栈顶元素中哪个更小。
        // 如果newNum更小或两者相等,将newNum入DataMin;否则,将stackMin的栈顶元素重复压入stackMin,
        // 即在栈顶元素上再压入一个栈顶元素。
        stack1(){
            this.stackData=new Stack<Integer>();
            this.stackMin=new Stack<Integer>();
        }
        public void push(int obj){
            stackData.push(obj);
            if(stackMin.isEmpty()){
                stackMin.push(obj);
            }else{
                if(obj<=stackMin.peek()){
                    stackMin.push(obj);
                }else{
                    stackMin.push(getMin());
                }
            }
        }
        public Integer pop(){
            if(stackData.isEmpty()){
                throw new RuntimeException("Stack is empty");
            }
            this.stackMin.pop();
            return stackData.pop();
        }
        public Integer getMin(){
            if(stackData.isEmpty()){
                throw new RuntimeException("Stack is empty");
            }
            return stackMin.peek();
        }
    }

第二种实现方案:
假设有栈stackData和栈stackMin。
假设当前数据为newNum,先将其压入stackData。然后判断stackMin是否为空。
如果stackMin为空,则将newNum也压入stackMin;否则,比较stackNum和stackMin的栈顶元素哪一个更小。
如果newNum比stackMin的栈顶元素更小或相等,将newNum也压入stackMin;否则,不压入。
出栈时,在stackData中弹出数据value。然后比较value和stackMin的栈顶元素的大小。
如果value等于stackMin的栈顶元素时,弹出stackMin的栈顶元素;如果value大于stackMin的栈顶元素时,返回stackMin的栈顶元素,不弹出。

 public static class stack2{
        Stack<Integer> stackData;
        Stack<Integer> stackMin;
        //假设有栈stackData和栈stackMin。
        //假设当前数据为newNum,先将其压入stackData。然后判断stackMin是否为空。
        //如果stackMin为空,则将newNum也压入stackMin;否则,比较stackNum和stackMin的栈顶元素哪一个更小。
        //如果newNum比stackMin的栈顶元素更小或相等,将newNum也压入stackMin;否则,不压入。
        //出栈时,在stackData中弹出数据value。然后比较value和stackMin的栈顶元素的大小。(vlaue只会大于或者等于stackMin的栈顶元素)
        //如果value等于stackMin的栈顶元素时,弹出stackMin的栈顶元素;如果value大于stackMin的栈顶元素时,返回stackMin的栈顶元素,不弹出。
        stack2(){
            this.stackData=new Stack<Integer>();
            this.stackMin=new Stack<Integer>();
        }
        public void push(int obj){
            stackData.push(obj);
            if(stackMin.isEmpty()){
                stackMin.push(obj);
            }else{
                if(obj<=stackMin.peek()){
                    stackMin.push(obj);
                }
            }
        }
        public Integer pop(){
            if(stackData.isEmpty()){
                throw new RuntimeException("Stack is empty");
            }
            if(stackData.peek()==this.getMin()){
                this.stackMin.pop();
            }
            return stackData.pop();
        }
        public Integer getMin(){
            if(stackData.isEmpty()){
                throw new RuntimeException("Stack is empty");
            }
            return stackMin.peek();
        }
    }

6.猫狗队列

【题目】 宠物、狗和猫的类如下: public class Pet { private String type; public Pet(String type) { this.type = type; } public String getPetType() { return this.type; } } public class Dog extends Pet { public Dog() { super("dog"); } } public class Cat extends Pet { public Cat() { super("cat"); } }
实现一种狗猫队列的结构,要求如下:
用户可以调用add方法将cat类或dog类的 实例放入队列中; 用户可以调用pollAll方法,将队列中所有的实例按照进队列 的先后顺序依次弹出; 用户可以调用pollDog方法,将队列中dog类的实例按照 进队列的先后顺序依次弹出; 用户可以调用pollCat方法,将队列中cat类的实 例按照进队列的先后顺序依次弹出; 用户可以调用isEmpty方法,检查队列中是 否还有dog或cat的实例; 用户可以调用isDogEmpty方法,检查队列中是否有dog 类的实例; 用户可以调用isCatEmpty方法,检查队列中是否有cat类的实例。
解决思路很简单,定义两个队列。
第一个队列是狗队列,第二个是猫队列。每个实例入队列的时候,都会记录一个类似时间戳的count。 用户调用pollAll方法的时候,根据count的大小,依次出队即可。其他的就正常入队出队即可。

public class DogCatQueue {
    public static class Pet{
        private String type;
        public Pet(String type){
            this.type=type;
        }
        public String getType(){
            return this.type;
        }
    }
    public static class Dog extends Pet{
        public  Dog(){
            super("dog");
        }
    }
    public static class Cat extends Pet{
        public  Cat(){
            super("cat");
        }
    }
    //count 类似时间戳
    public static class PetEnterQueue {
        private Pet pet;
        private long count;

        public PetEnterQueue(Pet pet, Long count) {
            this.count = count;
            this.pet = pet;
        }

        public Long getCount() {
            return this.count;
        }

        public String getType() {
            return this.pet.getType();
        }

        public Pet getPet() {
            return this.pet;
        }
    }
        public static class DogCatQueue01{
         private Queue<PetEnterQueue> dogQ;
         private Queue<PetEnterQueue> catQ;
         private Long count;

         public DogCatQueue01(){
             this.dogQ=new LinkedList<PetEnterQueue>();
             this.catQ=new LinkedList<PetEnterQueue>();
             this.count = (long)0;
         }
        public void add(Pet pet){
             if(pet.getType().equals("dog")){
                 dogQ.add(new PetEnterQueue(pet,count++));
             }else if(pet.getType().equals("cat")){
                 catQ.add(new PetEnterQueue(pet,count++));
             }else{
                 throw new RuntimeException("err,not dog or cat");
             }
        }
        public Pet pollAll(){
             if(!this.catQ.isEmpty()||!this.catQ.isEmpty()){
                if(this.dogQ.peek().getCount()<this.catQ.peek().getCount()){
                    return this.dogQ.poll().getPet();
                }else{
                    return this.catQ.poll().getPet();
                }
             }else if(!this.catQ.isEmpty()){
                return this.catQ.poll().getPet();
             }else if(!this.dogQ.isEmpty()){
                 return this.dogQ.poll().getPet();
            }else{
                 throw new RuntimeException("err,queue is empty");
             }
        }
        public Pet pollDog(){
            if(!this.dogQ.isEmpty()){
                return dogQ.poll().getPet();
            }else {
                throw new RuntimeException("err,dog queue is empty");
            }
         }
            public Pet pollCat(){
                if(!this.catQ.isEmpty()){
                    return catQ.poll().getPet();
                }else {
                    throw new RuntimeException("err,dog queue is empty");
                }
            }
            public boolean isEmpty() {
                return this.dogQ.isEmpty() && this.catQ.isEmpty();
            }

            public boolean isDogQueueEmpty() {
                return this.dogQ.isEmpty();
            }

            public boolean isCatQueueEmpty() {
                return this.catQ.isEmpty();
            }
        }

7.转圈打印矩阵

【题目】 给定一个整型矩阵matrix,请按照转圈的方式打印它。 例如: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 打印结果为:1,2,3,4,8,12,16,15,14,13,9, 5,6,7,11, 10
【要求】 额外空间复杂度为O(1)。
跳出局部思维。
定义一个打印边界(子矩阵)的函数,这个函数只要知道左上角的点坐标(tr,tc)和右下角的点坐标(dr,dc)就能打印这一圈的数字。有两种特殊情况,第一种左上角的行与右下角的行相同,则只要打印这一行的数字;第二种左上角的列与右下角的列相同,则只要打印这一列的数字。
首先打印最外圈,然后让tr和tc加1,令dr和dc减1,继续打印。如果发现左上角坐标跑到右下角坐标的右方和下方,整个过程就停止。

package ArraysAndMatrices;

import java.util.ArrayList;

public class PrintMatrixSpiralOrder {
    ArrayList<Integer> SOMatrix =new ArrayList<Integer>();
    //首先打印最外圈,然后让tr和tc加1,令dr和dc减1,继续打印。
    // 如果发现左上角坐标跑到右下角坐标的右方和下方,整个过程就停止。
    public  ArrayList<Integer> spiralOrderPrint(int[][] matrix){
        int tr=0;
        int tc=0;
        int dr=matrix.length-1;
        int dc=matrix[0].length-1;
        while(tr<=dr&&tc<=dc){
            printEdrdge(matrix,tr++,tc++,dr--,dc--);
        }
        return SOMatrix;
    }
    //定义一个打印边界(子矩阵)的函数,
    // 这个函数只要知道左上角的点坐标(tr,tc)和右下角的点坐标(dr,dc)就能打印这一圈的数字。
    // 有两种特殊情况,第一种左上角的行与右下角的行相同,则只要打印这一行的数字;
    // 第二种左上角的列与右下角的列相同,则只要打印这一列的数字。
    public  void printEdrdge(int[][] matrix,int tr,int tc,int dr,int dc){
        if(tr==dr){
            for(int i=tc;i<dc;i++){
                SOMatrix.add(matrix[tr][i++]);
            }
        }else if (tc==dc){
                for(int i=tr;i<dr;i++){
                    SOMatrix.add(matrix[i][tc]);
            }
        }
        //以下打印到边界前最后一个数字;如果只有一行,就会数组越界?
        int curC=tc;
        int curR=tr;
        while(curC!=dc){
            SOMatrix.add(matrix[tr][curC++]);
        }
        while(curR!=dr){
            SOMatrix.add(matrix[curR++][dc]);
        }
        while(curC!=tc){
            SOMatrix.add(matrix[dr][curC--]);
        }
        while(curR!=tr){
            SOMatrix.add(matrix[curR--][tc]);
        }
    }
    public static void main(String[] args) {
        PrintMatrixSpiralOrder printMatrixSpiralOrder=new PrintMatrixSpiralOrder();
        int[][] matrix = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 },
                { 13, 14, 15, 16 } };
        System.out.println(printMatrixSpiralOrder.spiralOrderPrint(matrix).toString());


    }
}

上题在我的每日一道编程题提过。加深一下理解。

8.旋转正方形矩阵

【题目】 给定一个整型正方形矩阵matrix,请把该矩阵调整成 顺时针旋转90度的样子。
【要求】 额外空间复杂度为O(1)。
和上题思路差不多。
定义一个能够旋转90度边界(子矩阵)的函数,这个函数只要知道左上角的点坐标(tr,tc)和右下角的点坐标(dr,dc)就能旋转边界数字90度。由于是正方形,不会出现只有一行或者一列的情况。
首先旋转最外圈,然后让tr和tc加1,令dr和dc减1,继续打印。如果发现左上角坐标跑到右下角坐标的地方(重合),整个过程停止。
旋转的过程就是抠边界的过程,每4个点进行一次90度旋转。

public class RotateMatrix {

    public int[][] rotate(int[][] matrix){
        int tr=0;
        int tc=0;
        int dr=matrix.length-1;
        int dc=matrix[0].length-1;
        while(tr<dr&&tc<dc){
            rotateEdge(matrix,tr++,tc++,dr--,dc--);
        }
        return matrix;

    }
    //定义一个能够旋转边界的函数
    //正方形。每4个点进行一次旋转。(只有一个边界)
    public void rotateEdge(int[][] matrix,int tr,int tc,int dr,int dc){
            int times=dc-tc;
            for(int i=0;i<times;i++){
                int temp=matrix[tr][tc+i];
                matrix[tr][tc+i]=matrix[dr-i][tc];
                matrix[dr-i][tc]=matrix[dr][dc-i];
                matrix[dr][dc-i]=matrix[tr+i][dc];
                matrix[tr+i][dc]=temp;
            } 
    }

9.“之”字形打印矩阵

【题目】 给定一个矩阵matrix,按照“之”字形的方式打印这 个矩阵,例如: 1 2 3 4 5 6 7 8 9 10 11 12 “之”字形打印的结果为:1,2,5,9,6,3,4,7,10,11, 8,12
【要求】 额外空间复杂度为O(1)。
由于是之字型打印,每次打印的都是一条斜线,设计出一个打印斜线的函数。
1.上坐标(tr,tc)初始为(0,0),沿着矩阵第一行移动(tc++),当到达第一行最右边的元素后,再沿着矩阵最后一列移动(tr++)。
2.下坐标(dr,dc)初始为(0,0),沿着矩阵第一列移动(dr++),当到达第一列最下边的元素后,再沿着矩阵最后一行移动(dc++)。
3.上坐标和下坐标同步移动,每次移动后打印斜线。
4.打印的方向用boolean值表示,每次取反。

package ArraysAndMatrices;

public class ZigZagPrintMatrix {
    public static void printMatrixZigZag(int[][] matrix){
        int tR=0;
        int tC=0;
        int dR=0;
        int dC=0;
        int endR=matrix.length-1;
        int endC=matrix[0].length-1;
        boolean fromUp=false;
        while(tR!=endR+1){
            printLevel(matrix,tR,tC,dR,dC,fromUp);
            //注意 tr=tr++;   就错了;且顺序不能错位,因为tC会自增
            tR=tC==endC?tR+1:tR;
            tC=tC==endC?endC:tC+1;
            dC=dR==endR?dC+1:dC;
            dR=dR==endR?endR:dR+1;
            fromUp=!fromUp;
        }
    }
    public static void printLevel(int[][] matrix,int tR,int tC,int dR,int dC,boolean f){
        if(f){
            while(tR!=dR+1){
                System.out.println(matrix[tR++][tC--]+" ");
            }
        }else{
            while(dR!=tR-1){
                System.out.println(matrix[dR--][dC++]+" ");
            }
        }
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容