LeetCode 431-460

432. 全 O(1) 的数据结构

class AllOne {
    class DLinkedNode {
        int val;
        Set<String> keys;
        DLinkedNode next;
        DLinkedNode pre;

        public DLinkedNode(int val) {
            this.val = val;
            this.keys = new HashSet<>();
        }
    }

    DLinkedNode head, tail;//   双向链表从head到tail的value值依次减小
    Map<String, Integer> map1;//key->val
    Map<Integer, DLinkedNode> map2;//val -> DLinkedNode

    public AllOne() {
        this.head = new DLinkedNode(0);
        this.tail = new DLinkedNode(0);
        head.next = tail;
        tail.pre = head;
        this.map1 = new HashMap<>();
        this.map2 = new HashMap<>();
    }

    public void inc(String key) {
        if (map1.containsKey(key)) {
            int val = map1.get(key);
            map1.put(key, val + 1);
            DLinkedNode node = map2.get(val);
            node.keys.remove(key);
            DLinkedNode preNode = node.pre;
            if (preNode == head || preNode.val > val + 1) {
                DLinkedNode newNode = new DLinkedNode(val + 1);
                newNode.keys.add(key);
                newNode.next = node;
                newNode.pre = preNode;
                preNode.next = newNode;
                node.pre = newNode;
                map2.put(val + 1, newNode);
                preNode = newNode;
            } else {
                preNode.keys.add(key);
            }
            // 如果原节点在移除key后size为0,则删除该节点,并在map2中删除val->node的映射
            if (node.keys.size() == 0) {
                preNode.next = node.next;
                node.next.pre = preNode;
                map2.remove(val);
            }
        } else {
            map1.put(key, 1);
            DLinkedNode node = map2.get(1);
            if (node == null) {
                DLinkedNode newNode = new DLinkedNode(1);
                // 如果当前没有统计次数为1的节点,则新建节点并插入到双向链表的尾部,因为统计次数最小为1
                // 并将1->newNode的映射加入到map2中
                newNode.keys.add(key);
                newNode.next = tail;
                newNode.pre = tail.pre;
                tail.pre.next = newNode;
                tail.pre = newNode;
                map2.put(1, newNode);
            } else {
                node.keys.add(key);
            }
        }

    }

    public void dec(String key) {
        if (map1.containsKey(key)) {
            // 获取当前统计次数
            int val = map1.get(key);
            // 当前统计次数对应的节点
            DLinkedNode node = map2.get(val);
            // 从节点的keys set中移除当前key
            node.keys.remove(key);
            // 如果原统计次数为1,从map1中移除当前key
            if (val == 1) {
                map1.remove(key);
            } else {
                map1.put(key, val - 1);
                DLinkedNode nextNode = node.next;
                if (nextNode == tail || nextNode.val < val - 1) {
                    DLinkedNode newNode = new DLinkedNode(val - 1);
                    newNode.keys.add(key);
                    newNode.pre = node;
                    newNode.next = nextNode;
                    node.next = newNode;
                    nextNode.pre = newNode;
                    map2.put(val - 1, newNode);
                } else {    // 下一个节点的统计次数为val-1,将key加到下一节点的keys Set中
                    nextNode.keys.add(key);
                }
            }
            if (node.keys.size() == 0) {
                node.pre.next = node.next;
                node.next.pre = node.pre;
                map2.remove(val);
            }
        }
    }

    public String getMaxKey() {
        if (head.next == tail) {
            return "";
        } else {
            return head.next.keys.iterator().next();
        }
    }

    public String getMinKey() {
        if (tail.pre == head) {
            return "";
        } else {
            return tail.pre.keys.iterator().next();
        }
    }
}

433. 最小基因变化

双向bfs,和 127. 单词接龙一模一样。

class Solution {
    public int minMutation(String start, String end, String[] bank) {
        char[] gene = {'A', 'G', 'C', 'T'};
        Set<String> set = new HashSet<>();
        for (String str : bank) {
            set.add(str);
        }
        set.add(start);
        if (set.isEmpty() || !set.contains(end)) {
            return -1;
        }
        Queue<String> q1 = new LinkedList<>();
        int step1 = 0;
        q1.offer(start);
        Set<String> isVisited1 = new HashSet<>();
        Queue<String> q2 = new LinkedList<>();
        int step2 = 0;
        q2.offer(end);
        Set<String> isVisited2 = new HashSet<>();
        while (!q1.isEmpty() && !q2.isEmpty()) {
            int size1 = q1.size();
            for (int i = 0; i < size1; i++) {
                String front = q1.poll();
                char[] chars = front.toCharArray();
                for (int j = 0; j < chars.length; j++) {
                    char temp = chars[j];
                    for (int k = 0; k < 4; k++) {
                        if (gene[k] == temp) {
                            continue;
                        }
                        chars[j] = gene[k];
                        String str = String.valueOf(chars);
                        if (end.equals(str)) {
                            return step1 + 1;
                        }
                        if (isVisited2.contains(str)) {
                            return step1 + step2 + 1;
                        }
                        if (set.contains(str) && !isVisited1.contains(str)) {
                            q1.offer(str);
                            isVisited1.add(str);
                        }
                    }
                    chars[j] = temp;
                }
            }
            step1++;
            int size2 = q2.size();
            for (int i = 0; i < size2; i++) {
                String front = q2.poll();
                char[] chars = front.toCharArray();
                for (int j = 0; j < chars.length; j++) {
                    char temp = chars[j];
                    for (int k = 0; k < 4; k++) {
                        if (gene[k] == temp) {
                            continue;
                        }
                        chars[j] = gene[k];
                        String str = String.valueOf(chars);
                        if (isVisited1.contains(str)) {
                            return step1 + step2 + 1;
                        }
                        if (set.contains(str) && !isVisited2.contains(str)) {
                            q2.offer(str);
                            isVisited2.add(str);
                        }
                    }
                    chars[j] = temp;
                }
            }
            step2++;
        }
        return -1;
    }
}

434. 字符串中的单词数

class Solution {
    public int countSegments(String s) {
        String[] splits = s.split(" ");
        int res = 0;
        for (String split : splits) {
            if (!"".equals(split)) {
                res++;
            }
        }
        return res;
    }
}

435. 无重叠区间

先把所有区间按照左端点从小到大排序。
然后遍历所有区间,只要某个区间的左端点小于前一个区间的右端点,那么有重复区间,需要移除某一个区间。
尽量保留右端点小的区间,尽量移除右端点大的区间。
这样移除区间的次数最优。

class Solution {
    public int eraseOverlapIntervals(int[][] intervals) {
        if (intervals.length == 0) {
            return 0;
        }
        Arrays.sort(intervals, (o1, o2) -> o1[0] - o2[0]);
        int res = 0;
        int end = intervals[0][1];
        int pre = 0;
        for (int i = 1; i < intervals.length; i++) {
            if (intervals[pre][1] > intervals[i][0]) {
                if (intervals[pre][1] > intervals[i][1]) {
                    pre = i;
                }
                res++;
            } else {
                pre = i;
            }
        }
        return res;
    }
}

436. 寻找右区间

暴力法:
时间复杂度On2

class Solution {
    public int[] findRightInterval(int[][] intervals) {
        int[] res = new int[intervals.length];
        for (int i = 0; i < intervals.length; i++) {
            int minIndex = -1, minValue = Integer.MAX_VALUE;
            for (int j = 0; j < intervals.length; j++) {
                if (j == i) {
                    continue;
                }
                if (intervals[j][0] >= intervals[i][1] && intervals[j][0] < minValue) {
                    minValue = intervals[j][0];
                    minIndex = j;
                }
            }
            res[i] = minIndex;
        }
        return res;
    }
}

排序+二分搜索:
时间复杂度O(nlogn)

class Solution {
    private int binarySearh(int target, int[] arr) {
        if (arr[arr.length - 1] < target) {
            return -1;
        }
        int lo = 0, hi = arr.length - 1;
        while (lo < hi) {
            int mid = lo + (hi - lo) / 2;
            if (arr[mid] >= target) {
                hi = mid;
            } else {
                lo = mid + 1;
            }
        }
        return lo;
    }

    public int[] findRightInterval(int[][] intervals) {
        Map<Integer, Integer> map = new HashMap<>();
        int[] arr = new int[intervals.length];
        for (int i = 0; i < intervals.length; i++) {
            arr[i] = intervals[i][0];
            map.put(intervals[i][0], i);
        }
        Arrays.sort(arr);
        int[] res = new int[intervals.length];
        for (int i = 0; i < intervals.length; i++) {
            int val = binarySearh(intervals[i][1], arr);
            if (val == -1) {
                res[i] = -1;
            } else {
                res[i] = map.get(arr[val]);
            }
        }
        return res;
    }
}

437. 路径总和 III

class Solution {
    int res = 0;

    public int pathSum(TreeNode root, int sum) {
        if (root == null) {
            return 0;
        }
        dfs(root, sum);
        pathSum(root.left, sum);
        pathSum(root.right, sum);
        return res;
    }

    private void dfs(TreeNode root, int sum) {
        if (root == null) {
            return;
        }
        sum -= root.val;
        if (sum == 0) {
            res++;
        }
        dfs(root.left, sum);
        dfs(root.right, sum);
    }
}

438. 找到字符串中所有字母异位词

暴力法:

class Solution {
    public List<Integer> findAnagrams(String s, String p) {
        List<Integer> res = new ArrayList<>();
        int[] count = new int[26];
        for (char c : p.toCharArray()) {
            count[c - 'a']++;
        }
        for (int i = 0; i < s.length() - p.length()+1; i++) {
            boolean flag = false;
            String sub = s.substring(i, i + p.length());
            int[] count2 = new int[26];
            for (char c : sub.toCharArray()) {
                count2[c - 'a']++;
            }
            for (int j = 0; j < 26; j++) {
                if (count[j] != count2[j]) {
                    flag = true;
                    break;
                }
            }
            if (flag == true) {
                continue;
            }
            res.add(i);
        }
        return res;
    }
}

没必要每次都重新计算窗口内的字符,只需在移动窗口的过程中增减边界的字符数即可。
滑动窗口:

class Solution {
    public List<Integer> findAnagrams(String s, String p) {
        if (s.length() < p.length()) {
            return new ArrayList<>();
        }
        List<Integer> res = new ArrayList<>();
        int[] count = new int[26];
        for (char c : p.toCharArray()) {
            count[c - 'a']++;
        }
        int len = p.length();//窗口大小
        int[] cur = new int[26];
        for (int i = 0; i < len - 1; i++) {
            cur[s.charAt(i) - 'a']++;
        }
        for (int i = len - 1; i < s.length(); i++) {
            cur[s.charAt(i) - 'a']++;
            if (judge(cur, count)) {
                res.add(i - len + 1);
            }
            cur[s.charAt(i - len + 1) - 'a']--;
        }
        return res;
    }

    //判断是否相等
    private boolean judge(int[] a, int[] b) {
        for (int i = 0; i < 26; i++) {
            if (a[i] != b[i]) {
                return false;
            }
        }
        return true;
    }
}

440. 字典序的第K小数字

class Solution {
    public int findKthNumber(int n, int k) {
        int cur = 1;
        k--;
        while (k > 0) {
            long curNum = 0;
            long first = cur;
            long next = cur + 1;
            while (first <= n) {
                curNum += Math.min((long) (n + 1), next) - first;
                first *= 10;
                next *= 10;
            }
            if (curNum <= k) {
                cur++;
                k -= curNum;
            } else {
                k--;
                cur *= 10;
            }
        }
        return cur;
    }
}

441. 排列硬币

class Solution {
    public int arrangeCoins(int n) {
        int res = 1;
        while (n >= res) {
            n -= res;
            res++;
        }
        return res-1;
    }
}

442. 数组中重复的数据

题目说了1 ≤ a[i] ≤ n,说明数组内的每个数-1之后都可以对应到数组的某个下标0~n-1。
遍历数组,把nums[i]-1位置的数取反,如果取反之后,这个位置的数还大于0,说明nums[i]这个数出现了两次,加到结果中。

class Solution {
    public List<Integer> findDuplicates(int[] nums) {
        List<Integer> res = new ArrayList<>();
        for (int i = 0; i < nums.length; i++) {
            int index = Math.abs(nums[i]) - 1;
            nums[index] = -nums[index];
            if (nums[index] > 0) {
                res.add(Math.abs(nums[i]));
            }
        }
        return res;
    }
}

443. 压缩字符串

class Solution {
    public int compress(char[] chars) {
        int len = 0;//压缩完之后的长度
        int begin = 0;//连续字符串的起始位置
        for (int i = 0; i < chars.length; i++) {
            if (i == chars.length - 1 || chars[i] != chars[i + 1]) {
                chars[len] = chars[begin];
                len++;
                if (i > begin) {//大于一个字符才进行压缩
                    for (char c : ("" + (i - begin + 1)).toCharArray()) {
                        chars[len] = c;
                        len++;
                    }
                }
                begin = i + 1;
            }
        }
        return len;
    }
}

445. 两数相加 II

class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        Deque<Integer> stack1 = new ArrayDeque<>();
        Deque<Integer> stack2 = new ArrayDeque<>();
        while (l1 != null) {
            stack1.push(l1.val);
            l1 = l1.next;
        }
        while (l2 != null) {
            stack2.push(l2.val);
            l2 = l2.next;
        }
        ListNode dummy = new ListNode(0);
        int carry = 0;
        while (!stack1.isEmpty() || !stack2.isEmpty() || carry != 0) {
            int a = stack1.isEmpty() ? 0 : stack1.pop();
            int b = stack2.isEmpty() ? 0 : stack2.pop();
            int sum = a + b + carry;
            ListNode node = new ListNode(sum % 10);
            node.next = dummy.next;
            dummy.next = node;
            carry = sum / 10;
        }
        return dummy.next;
    }
}

447. 回旋镖的数量

class Solution {
    public int numberOfBoomerangs(int[][] points) {
        int res = 0;
        for (int[] point : points) {
            Map<Long, Integer> map = new HashMap<>();
            for (int[] point2 : points) {
                int dx = point2[0] - point[0];
                int dy = point2[1] - point[1];
                long dis = dx * dx + dy * dy;
                map.put(dis, map.getOrDefault(dis, 0) + 1);
            }
            for (int val : map.values()) {
                res += val * (val - 1);
            }
        }
        return res;
    }
}

448. 找到所有数组中消失的数字

先遍历的一次,将a[i]-1位置的数变成负数。
再遍历一次,只要a[i]是正数,那么i+1就是没出现过的数。

class Solution {
    public List<Integer> findDisappearedNumbers(int[] nums) {
        List<Integer> res = new ArrayList<>();
        for (int i = 0; i < nums.length; i++) {
            int index = Math.abs(nums[i]) - 1;
            nums[index] = -Math.abs(nums[index]);
        }
        for (int i = 0; i < nums.length; i++) {
            if (nums[i] > 0) {
                res.add(i + 1);
            }
        }
        return res;
    }
}

449. 序列化和反序列化二叉搜索树

public class Codec {
    public String serialize(TreeNode root) {
        if (root == null) {
            return "null";
        }
        StringBuilder res = new StringBuilder();
        Queue<TreeNode> q = new LinkedList<>();
        q.offer(root);
        while (!q.isEmpty()) {
            int size = q.size();
            for (int i = 0; i < size; i++) {
                TreeNode front = q.poll();
                if (front == null) {
                    res.append("null,");
                    continue;
                } else {
                    res.append(front.val + ",");
                    q.offer(front.left);
                    q.offer(front.right);
                }
            }
        }
        res.deleteCharAt(res.length() - 1);
        return res.toString();
    }

    public TreeNode deserialize(String data) {
        if ("null".equals(data)) {
            return null;
        }
        String[] splits = data.split(",");
        TreeNode root = new TreeNode(Integer.parseInt(splits[0]));
        Queue<TreeNode> q = new LinkedList<>();
        q.offer(root);
        for (int i = 1; i < splits.length; i++) {
            TreeNode front = q.poll();
            if (!"null".equals(splits[i])) {
                front.left = new TreeNode(Integer.parseInt(splits[i]));
                q.offer(front.left);
            }
            i++;
            if (!"null".equals(splits[i])) {
                front.right = new TreeNode(Integer.parseInt(splits[i]));
                q.offer(front.right);
            }
        }
        return root;
    }
}

450. 删除二叉搜索树中的节点

class Solution {
    private int getSuccessor(TreeNode root) {
        root = root.right;
        while (root.left != null) {
            root = root.left;
        }
        return root.val;
    }

    private int getPredecessor(TreeNode root) {
        root = root.left;
        while (root.right != null) {
            root = root.right;
        }
        return root.val;
    }

    public TreeNode deleteNode(TreeNode root, int key) {
        if (root == null) {
            return null;
        }
        if (root.val > key) {
            root.left = deleteNode(root.left, key);
        } else if (root.val < key) {
            root.right = deleteNode(root.right, key);
        } else {
            if (root.left == null && root.right == null) {
                root = null;
            } else if (root.left != null) {
                root.val = getPredecessor(root);
                root.left = deleteNode(root.left, root.val);
            } else {
                root.val = getSuccessor(root);
                root.right = deleteNode(root.right, root.val);
            }
        }
        return root;
    }
}

451. 根据字符出现频率排序

class Solution {
    public <K extends Comparable, V extends Comparable> Map<K, V> sortMapByValues(Map<K, V> aMap) {
        HashMap<K, V> finalOut = new LinkedHashMap<>();
        aMap.entrySet()
                .stream()
                .sorted((p1, p2) -> p2.getValue().compareTo(p1.getValue()))
                .collect(Collectors.toList()).forEach(ele -> finalOut.put(ele.getKey(), ele.getValue()));
        return finalOut;
    }

    public String frequencySort(String s) {
        Map<Character, Integer> map = new HashMap<>();
        for (char c : s.toCharArray()) {
            map.put(c, map.getOrDefault(c, 0) + 1);
        }
        Map<Character, Integer> sorted = sortMapByValues(map);
        StringBuilder res = new StringBuilder();
        for (char c : sorted.keySet()) {
            int num = sorted.get(c);
            for (int i = 0; i < num; i++) {
                res.append(c);
            }
        }
        return res.toString();
    }
}

452. 用最少数量的箭引爆气球

每次射右边界一定是最优的情况,按照右边界从小到大排序。
注意以后lambda表达式里面不要写o1[1] - o2[1]了,可能会溢出造成错误的排序。改成Integer.compare(o1[1], o2[1]))。

class Solution {
    public int findMinArrowShots(int[][] points) {
        if (points.length == 0) {
            return 0;
        }
        Arrays.sort(points, (o1, o2) -> Integer.compare(o1[1], o2[1]));
        int res = 1;
        int right = points[0][1];
        for (int[] point : points) {
            if (point[0] > right) {
                right = point[1];
                res++;
            }
        }
        return res;
    }
}

453. 最小移动次数使数组元素相等

class Solution {
    public int minMoves(int[] nums) {
        int res = 0;
        int min = nums[0];
        for (int i = 1; i < nums.length; i++) {
            min = Math.min(min, nums[i]);
        }
        for (int i : nums) {
            if (i > min) {
                res += i - min;
            }
        }
        return res;
    }
}

454. 四数相加 II

分成两组做

class Solution {
    public int fourSumCount(int[] A, int[] B, int[] C, int[] D) {
        int res = 0;
        Map<Integer, Integer> map = new HashMap<>();
        for (int i : A) {
            for (int j : B) {
                map.put(i + j, map.getOrDefault(i + j, 0) + 1);
            }
        }
        for (int i : C) {
            for (int j : D) {
                if (map.containsKey(-i - j)) {
                    res += map.get(-i - j);
                }
            }
        }
        return res;
    }
}

455. 分发饼干

class Solution {
    public int findContentChildren(int[] g, int[] s) {
        Arrays.sort(g);
        Arrays.sort(s);
        int i = 0, j = 0;
        int res = 0;
        while (i < g.length && j < s.length) {
            if (g[i] <= s[j]) {
                i++;
                j++;
                res++;
            } else {
                j++;
            }
        }
        return res;
    }
}

456. 132模式

class Solution {
    public boolean find132pattern(int[] nums) {
        if (nums.length == 0) {
            return false;
        }
        int[] min = new int[nums.length];
        min[0] = nums[0];
        for (int i = 1; i < nums.length; i++) {
            min[i] = Math.min(min[i - 1], nums[i]);
        }
        Deque<Integer> stack = new ArrayDeque<>();
        for (int i = nums.length - 1; i >= 0; i--) {
            if (nums[i] > min[i]) {
                while (!stack.isEmpty() && stack.peek() <= min[i]) {
                    stack.pop();
                }
                if (!stack.isEmpty() && stack.peek() < nums[i]) {
                    return true;
                }
                stack.push(nums[i]);
            }
        }
        return false;
    }
}

457. 环形数组循环

class Solution {
    private int getNext(int[] nums, int i, int next) {
        return (i + next % nums.length + nums.length) % nums.length;
    }

    public boolean circularArrayLoop(int[] nums) {
        int len = nums.length;
        for (int i = 0; i < nums.length; i++) {
            boolean[] isVisited = new boolean[len];
            int j = i;
            int count = 0;
            while (isVisited[j] == false) {
                isVisited[j] = true;
                if (nums[j] > 0) {
                    j = getNext(nums, j, nums[j]);
                    if (nums[j] < 0) {
                        break;
                    }
                    count++;
                } else {
                    j = getNext(nums, j, nums[j]);
                    if (nums[j] > 0) {
                        break;
                    }
                    count++;
                }
            }
            if (j == i && count > 1) {
                return true;
            }
        }
        return false;
    }
}

458. 可怜的小猪

对于一只猪,可以在1h之内最多喝 4次水(60/15),但是可以检验5个桶,如果前四次没死,说明第5个桶有毒。

对于2只猪,现在可以让一只猪一下喝5桶水,如图所示的一只猪喝的五个,一只猪喝的五个,这样就可以确定哪个桶有毒,可以检测25个桶。

3只猪可以检测125个桶。

class Solution {
    public int poorPigs(int buckets, int minutesToDie, int minutesToTest) {
        int pigs = 0;
        while (Math.pow((minutesToTest / minutesToDie + 1), pigs) < buckets) {
            pigs++;
        }
        return pigs;
    }
}

459. 重复的子字符串

class Solution {
    public boolean repeatedSubstringPattern(String s) {
        return (s + s).indexOf(s, 1) != s.length();
    }
}

460. LFU 缓存

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

推荐阅读更多精彩内容