LeetCode Week Contest

本週題目比較簡單暴力。
1252. Cells with Odd Values in a Matrix
暴力模擬

class Solution {
    public int oddCells(int n, int m, int[][] indices) {
     
        
        int ans=0;
        int[][] chess=new int[n][m];
        for(int[] a:indices){
            
            for(int i=0;i<m;i++)
                chess[a[0]][i]+=1;
            for(int i=0;i<n;i++)
                chess[i][a[1]]+=1;
        }
        
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                if((chess[i][j] & 1)==1)
                    ans++;
            }
        }
        return ans;
    }
}

1253. Reconstruct a 2-Row Binary Matrix
暴力方法

class Solution {
    public List<List<Integer>> reconstructMatrix(int upper, int lower, int[] colsum) {
        int cols=colsum.length;
        int[][] nums=new int[2][cols];
        ArrayList<Integer> left=new ArrayList<>();
        int count=0;
        for(int i=0;i<cols;i++){
            if(colsum[i]==2){
                nums[0][i]=1;
                nums[1][i]=1;
                upper--;
                lower--;
            }
            if(colsum[i]==1){
                left.add(i);
                count++;
            }
            
        }
        if(count!=upper+lower)
            return new LinkedList<>();
        for(int i=0;i<left.size();i++){
            if(upper>lower){
                nums[0][left.get(i)]=1;
                upper--;
            }
            else{
                nums[1][left.get(i)]=1;
                lower--;
            }
        }
        if(upper==0 && lower==0){
            
            LinkedList<List<Integer>> ans=new LinkedList<>();
            for(int i=0;i<2;i++){
                LinkedList<Integer> tmp=new LinkedList<>();
                for(int j=0;j<cols;j++)
                    tmp.add(nums[i][j]);
                ans.add(tmp);
            }
            return ans;
        }
        else
        {
            return new LinkedList<>();
        }
    }
}

1254. Number of Closed Islands
經典的BFS似曾相識

class Solution {
    
    static class Coordinate{
        int x,y; 
        public Coordinate(int x,int y){
            this.x=x;
            this.y=y;
        }     
    }
    
    int[] dirsX={0,0,1,-1};
    int[] dirsY={-1,1,0,0};
    
    
    public int closedIsland(int[][] grid) {
        
        int ans=0;
        int m=grid.length,n=grid[0].length;
        boolean[][] visited=new boolean[m][n];
        
        for(int i=1;i<m-1;i++)
        {
            for(int j=1;j<n-1;j++)
            {
                if(grid[i][j]==0 && !visited[i][j])
                {
                    boolean flag=false;
                    Queue<Coordinate> q=new LinkedList<>();
                    q.add(new Coordinate(i,j));
                    
                    while(!q.isEmpty()){
                        Coordinate tmp=q.poll();
                        int x=tmp.x,y=tmp.y;
                        if(x==0 || x==m-1 || y==0 || y==n-1)
                            flag=true;
                        for(int k=0;k<4;k++){
                            int x1=x+dirsX[k],y1=y+dirsY[k];
                            if((x1>=0 && x1<m) && (y1>=0 && y1<n) && grid[x1][y1]==0 && !visited[x1][y1]){
                                visited[x1][y1]=true;
                                q.add(new Coordinate(x1,y1));   
                            }
                        }
                    }
                    if(!flag)
                        ans++;
                }
            }
        }
        return ans;
    }
}

1255. Maximum Score Words Formed by Letters
經典的狀態壓縮動態規劃似曾相識

class Solution {
    
    public static boolean isChosen(int i,int j){
        if(((i>>j) & 1)==1)
            return true;
        else
            return false;
    }
        
    public static boolean canDistribute(String word,int[] curCount){
        
        
        for(int i=0;i<word.length();i++){
            
            if(curCount[word.charAt(i)-'a']>=1)
                curCount[word.charAt(i)-'a']--;
            else
                return false;    
        }
        return true;
    }
    
    public int maxScoreWords(String[] words, char[] letters, int[] score) {
        
        
        int n=words.length;
        
        //可選字母計數
        int[] count=new int[26];
        for(char c:letters){
            count[c-'a']++;
        }
        
        //候選單詞得分
        int[] scores=new int[n];
        
        for(int j=0;j<words.length;j++)
        {
            String word=words[j];
            for(int i=0;i<word.length();i++)
            {
                scores[j]+=score[word.charAt(i)-'a'];
            }
        }
        
        int N=1<<n,ans=0;
        for(int i=0;i<N;i++){
            
            int curMax=0;
            int[] curCount=new int[26];
            for(int k=0;k<26;k++)
                curCount[k]=count[k];
            for(int j=0;j<n;j++)
            {
                if(isChosen(i,j))
                {
                    if(canDistribute(words[j],curCount))
                        curMax+=scores[j];
                    else
                        break;
                } 
            }
            ans=Math.max(ans,curMax);
        }      
        return ans;
    }
}

1266. Minimum Time Visiting All Points
按順序訪問二維座標點,每一步只能水平、豎直、正對角移動一個單元格,對於相鄰點構成正方形的情況,所需步數爲正方形的邊長;對於矩形情況,也容易看出所需步數爲矩形長邊的長度。因此將兩條規則統一:

class Solution {
    public int minTimeToVisitAllPoints(int[][] points) {
        
        int ans=0;
        for(int i=1;i<points.length;i++){
            ans+=Math.max(Math.abs(points[i][0]-points[i-1][0]),Math.abs(points[i][1]-points[i-1][1]));
        }
        return ans;
    }
}

1267. Count Servers that Communicate
能夠通信的服務器必然在同一行或者同一列,也就是說在空十字線上的服務器被忽略,類似八皇后裏面標記行列狀態的技巧,需要用行數組和列數組來記錄服務器的數量

class Solution {
    public int countServers(int[][] grid) {
        
        int[] recordRow=new int[250];
        int[] recordCol=new int[250];
        
        int m=grid.length;
        int n=grid[0].length;
        
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(grid[i][j]!=0)
                {
                    recordRow[i]++;
                    recordCol[j]++;
                }
            }
        }
        int ans=0;
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++)
            {
                if( grid[i][j] == 1 && ( recordRow[i]>1 || recordCol[j]>1 ))
                {
                    //System.out.println(i+" "+j);
                    ans++;
                }
            }
        }
        return ans;
    }
}

1268. Search Suggestions System
這個問題是Trie的加強(實現他的應用功能:拼寫提示),這裏原封不動拷貝Trie Implementation的代碼,核心代碼是對Trie的深度優先遍歷操作,對於輸入不斷增加的字母,(新)前綴的搜索定位都需要從Trie根節點開始,這一步是相對冗餘的操作,可以進一步優化。
算法一:

class Solution {

    public static int count = 0;

    public static int MAX = 3;

    public List<List<String>> suggestedProducts(String[] products, String searchWord) {
        List<List<String>> ans = new LinkedList<>();
        Trie trie = new Trie();

        for (int i = 0; i < products.length; i++) {
            trie.insert(products[i]);
        }
        for (int i = 0; i < searchWord.length(); i++) {
            count = 0;
            String prefix = searchWord.substring(0, i + 1);
            List<String> record = new LinkedList<>();
            TrieNode node = trie.searchPrefix(prefix);
            if(node!=null){
                if(node.isEnd){
                    record.add(prefix);
                    count++;
                }
                collect(prefix, node, record);
            }
            ans.add(record);
        }
        return ans;
    }

    public void collect(String cur, TrieNode node, List<String> record) {

        if (count == MAX)
            return;
        for (char c = 'a'; c <= 'z' && count<MAX; c++) {

            if (node.containsKey(c)) {
                String next = cur + c;
                if (node.get(c).isEnd) {
                    record.add(next);
                    count++;
                }
                collect(next, node.get(c), record);
            }
        }
    }

    class TrieNode {

        private TrieNode[] links;
        private final int R = 26;
        private boolean isEnd;

        public TrieNode() {
            links = new TrieNode[R];
        }

        public boolean containsKey(char c) {
            return links[c - 'a'] != null;
        }

        public TrieNode get(char c) {
            return links[c - 'a'];
        }

        public void put(char c, TrieNode node) {
            links[c - 'a'] = node;
        }

        public void setEnd() {
            isEnd = true;
        }
    }

    class Trie {

        private TrieNode root;

        /**
         * Initialize your data structure here.
         */
        public Trie() {
            root = new TrieNode();
        }

        /**
         * Inserts a word into the trie.
         */
        public void insert(String word) {
            TrieNode node = root;
            for (int i = 0; i < word.length(); i++) {
                char curChar = word.charAt(i);
                if (!node.containsKey(curChar))
                    node.put(curChar, new TrieNode());
                node = node.get(curChar);
            }
            node.setEnd();
        }

        /*
        返回以word爲前綴的Trie節點

         */
        private TrieNode searchPrefix(String word) {
            TrieNode node = root;
            for (int i = 0; i < word.length(); i++) {
                char curChar = word.charAt(i);
                if (node.containsKey(curChar))
                    node = node.get(curChar);
                else
                    return null;
            }
            return node;
        }

        /**
         * Returns if the word is in the trie.
         */
        public boolean search(String word) {
            TrieNode node = searchPrefix(word);
            return node != null && node.isEnd;
        }

        /**
         * Returns if there is any word in the trie that starts with the given prefix.
         */
        public boolean startsWith(String prefix) {
            TrieNode node = searchPrefix(prefix);
            return node != null;
        }
    }
    
    /*
    public static void main(String[] args) {

        String[] strs = {"mobile", "mouse", "moneypot", "monitor", "mousepad"};
        String searchWord = "mouse";
        SearchSuggestions ss = new SearchSuggestions();
        List<List<String>> ans = ss.suggestedProducts(strs, searchWord);
        for (List<String> t : ans) {
            for (String s : t) {
                System.out.print(s + " ");
            }
            System.out.println();
        }
    }
    */
}

算法二:有點暴力匹配的意思,算法比較直觀,先按字典序排序,然後,枚舉可能的前綴與產品名一一匹配。看着複雜度比較大,實際運行起來速度挺快。

public List<List<String>> suggestedProducts(String[] products, String searchWord) {
    List<List<String>> results = new ArrayList<>();

    if(products == null || products.length == 0) return results;

	// sort the products lexicographically
    Arrays.sort(products);

    for(int i = 1; i <= searchWord.length(); i++) {
        List<String> temp = new ArrayList<>();
        int count = 0;
        for(String product : products) {
            if(product.length() >= i && product.substring(0, i).equals(searchWord.substring(0, i))) {
                temp.add(product);
                count++;
                if(count >= 3) {
                    break;
                }
            }
        }
        results.add(temp);
    }
    return results;
}

1269. Number of Ways to Stay in the Same Place After Some Steps
狀態轉移方程:
dp[i,j]ijdp[i,j]=dp[i1,j1]+dp[i1,j]+dp[i1,j+1] dp[i,j]表示花費i步到達位置j所需的步數。 \\ dp[i,j]=dp[i-1,j-1]+dp[i-1,j]+dp[i-1,j+1]

class Solution {
    public static int MOD=1000000007;
    public int numWays(int steps, int arrLen) {
        
        int[] dp1=new int[arrLen+2];
        dp1[1]=1;
        int[] dp2=new int[arrLen+2];
        int n=Math.min(steps,arrLen);
        for(int i=0;i<steps;i++)
        {
            for(int j=1;j<n+1;j++)
                dp2[j]=((dp1[j-1]+dp1[j])%MOD+dp1[j+1])%MOD;
            int[] tmp=dp1;
            dp1=dp2;
            dp2=tmp;
        }
        return dp1[1]; 
    }
}

萬年第四道不會,這該怎麼提高呀!!!
1184. Distance Between Bus Stops

class Solution {
    public int distanceBetweenBusStops(int[] distance, int start, int destination) {
        
        int dist=0,dist1=0;
        if(start>destination){
            int tmp=start;
            start=destination;
            destination=tmp;
        }
        for(int i=0;i<distance.length;i++){
            dist+=distance[i];
            if(i>=start && i<destination){
                dist1+=distance[i];
            }
        }
        return Math.min(dist-dist1,dist1);
    }
}

1185. Day of the Week

class Solution {
    
    public static int[][] monthLength={{31,28,31,30,31,30,31,31,30,31,30,31},{31,29,31,30,31,30,31,31,30,31,30,31}};
    
    public static String[] symbols={"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
    
    public static boolean isleap(int year){
        if(year%4==0&&year%100!=0||year%400==0)
            return true;
        else
            return false;
    }
    
    public String dayOfTheWeek(int day, int month, int year) {
         
        int sum=0,cur=0;
        for(int i=1971;i<year;i++){
            sum+=isleap(i)?366:365;
        }
        
        if(isleap(year)){     //29天
            for(int i=0;i<month-1;i++){
                cur+=monthLength[1][i];
            }
        }
        else{
            for(int i=0;i<month-1;i++){
                cur+=monthLength[0][i];
            }
        }
        sum+=cur+day;
        return symbols[(5+(sum-1)%7)%7];
        
    }
}

1186. Maximum Subarray Sum with One Deletion

class Solution {
    public int maximumSum(int[] arr) {
        
        int n=arr.length;
        int[] endHere=new int[n];
        endHere[0]=arr[0];
        int max=arr[0];
        for(int i=1;i<n;i++)
        {
            endHere[i]=Math.max(endHere[i-1]+arr[i],arr[i]);
            max=Math.max(max,endHere[i]);
        }
        
        int[] startHere=new int[n];
        startHere[n-1]=arr[n-1];
        for(int i=n-2;i>=0;i--){
            startHere[i]=Math.max(startHere[i+1]+arr[i],arr[i]);
            max=Math.max(max,startHere[i]);
        }
        
        for(int i=1;i<n-1;i++){
            max=Math.max(max,endHere[i-1]+startHere[i+1]);
        }
        return max;  
    }
}

1187. Make Array Strictly Increasing

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章