力扣---2020.4.13

355. 設計推特

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Set;

public class Twitter {

    /**
     * 用戶 id 和推文(單鏈表)的對應關係
     */
    private Map<Integer, Tweet> twitter;

    /**
     * 用戶 id 和他關注的用戶列表的對應關係
     */
    private Map<Integer, Set<Integer>> followings;

    /**
     * 全局使用的時間戳字段,用戶每發佈一條推文之前 + 1
     */
    private static int timestamp = 0;

    /**
     * 合併 k 組推文使用的數據結構(可以在方法裏創建使用),聲明成全局變量非必需,視個人情況使用
     */
    private static PriorityQueue<Tweet> maxHeap;

    /**
     * Initialize your data structure here.
     */
    public Twitter() {
        followings = new HashMap<>();
        twitter = new HashMap<>();
        maxHeap = new PriorityQueue<>((o1, o2) -> -o1.timestamp + o2.timestamp);
    }

    /**
     * Compose a new tweet.
     */
    public void postTweet(int userId, int tweetId) {
        timestamp++;
        if (twitter.containsKey(userId)) {
            Tweet oldHead = twitter.get(userId);
            Tweet newHead = new Tweet(tweetId, timestamp);
            newHead.next = oldHead;
            twitter.put(userId, newHead);
        } else {
            twitter.put(userId, new Tweet(tweetId, timestamp));
        }
    }

    /**
     * Retrieve the 10 most recent tweet ids in the user's news feed. Each item in the news feed must be posted by users who the user followed or by the user herself. Tweets must be ordered from most recent to least recent.
     */
    public List<Integer> getNewsFeed(int userId) {
        // 由於是全局使用的,使用之前需要清空
        maxHeap.clear();

        // 如果自己發了推文也要算上
        if (twitter.containsKey(userId)) {
            maxHeap.offer(twitter.get(userId));
        }

        Set<Integer> followingList = followings.get(userId);
        if (followingList != null && followingList.size() > 0) {
            for (Integer followingId : followingList) {
                Tweet tweet = twitter.get(followingId);
                if (tweet != null) {
                    maxHeap.offer(tweet);
                }
            }
        }

        List<Integer> res = new ArrayList<>(10);
        int count = 0;
        while (!maxHeap.isEmpty() && count < 10) {
            Tweet head = maxHeap.poll();
            res.add(head.id);

            // 這裏最好的操作應該是 replace,但是 Java 沒有提供
            if (head.next != null) {
                maxHeap.offer(head.next);
            }
            count++;
        }
        return res;
    }


    /**
     * Follower follows a followee. If the operation is invalid, it should be a no-op.
     *
     * @param followerId 發起關注者 id
     * @param followeeId 被關注者 id
     */
    public void follow(int followerId, int followeeId) {
        // 被關注人不能是自己
        if (followeeId == followerId) {
            return;
        }

        // 獲取我自己的關注列表
        Set<Integer> followingList = followings.get(followerId);
        if (followingList == null) {
            Set<Integer> init = new HashSet<>();
            init.add(followeeId);
            followings.put(followerId, init);
        } else {
            if (followingList.contains(followeeId)) {
                return;
            }
            followingList.add(followeeId);
        }
    }


    /**
     * Follower unfollows a followee. If the operation is invalid, it should be a no-op.
     *
     * @param followerId 發起取消關注的人的 id
     * @param followeeId 被取消關注的人的 id
     */
    public void unfollow(int followerId, int followeeId) {
        if (followeeId == followerId) {
            return;
        }

        // 獲取我自己的關注列表
        Set<Integer> followingList = followings.get(followerId);

        if (followingList == null) {
            return;
        }
        // 這裏刪除之前無需做判斷,因爲查找是否存在以後,就可以刪除,反正刪除之前都要查找
        followingList.remove(followeeId);
    }

    /**
     * 推文類,是一個單鏈表(結點視角)
     */
    private class Tweet {
        /**
         * 推文 id
         */
        private int id;

        /**
         * 發推文的時間戳
         */
        private int timestamp;
        private Tweet next;

        public Tweet(int id, int timestamp) {
            this.id = id;
            this.timestamp = timestamp;
        }
    }
}

面試題38. 字符串的排列

//回溯法
class Solution {
    List<String> res = new LinkedList<>();
    char[] c;
    public String[] permutation(String s) {
        c = s.toCharArray();
        dfs(0);
        return res.toArray(new String[res.size()]);
    }
    void dfs(int x) {
        if(x == c.length - 1) {
            res.add(String.valueOf(c)); // 添加排列方案
            return;
        }
        HashSet<Character> set = new HashSet<>();
        for(int i = x; i < c.length; i++) {
            if(set.contains(c[i])) continue; // 重複,因此剪枝
            set.add(c[i]);
            swap(i, x); // 交換,固定此位爲 c[i] 
            dfs(x + 1); // 開啓固定第 x + 1 位字符
            swap(i, x); // 恢復交換
        }
    }
    void swap(int a, int b) {
        char tmp = c[a];
        c[a] = c[b];
        c[b] = tmp;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章