leetcode刷题总结851-900

851. 喧闹和富有

  描述:
    

 

 

   思路:深度优先(带记忆)。  这个题有点秒。。

853. 车队

  描述:

    

 

 

   思路:

    我们首先对这些车辆按照它们的起始位置降序排序,并且用 (target - position) / speed 计算出每辆车在不受其余车的影响时,行驶到终点需要的时间。对于相邻的两辆车 S 和 F,F 的起始位置大于 S,如果 S 行驶到终点需要的时间小于等于 F,那么 S 一定会在终点前追上 F 并形成车队。这是因为在追上 F 之前,S 的行驶速度并不会减小,而 F 却有可能因为追上前面的车辆而速度减小,因此 S 总能在终点前追上 F。

854. 相似度为 K 的字符串

  描述:

    

 

 

   思路:

class Solution {
public:

    int res , n ;

    void dfs(int pos , int step , string& A , string &B) {
        if (step >= res)
            return ;
        if (pos == n) {
            res = min(res , step) ;
            return ;
        }
        if (A[pos] == B[pos]) {
            dfs(pos + 1 , step , A , B) ;
        } else {
            for (int i = pos + 1 ; i < n ; ++i) {
                if (A[i] == B[pos] && A[i] != B[i]) {
                    swap(A[i] , A[pos]) ;
                    dfs(pos + 1 , step + 1 , A , B) ;
                    swap(A[i] , A[pos]) ;
                }
            }
        }
    }

    int kSimilarity(string A, string B) {
        n = A.length() ;
        res = n + 1 ;
        dfs(0 , 0 , A , B) ;
        return res ;
    }
};
View Code

856. 括号的分数

  描述:

    

 

 

   思路:栈

861. 翻转矩阵后的得分

  描述:

    

 

 

   思路:

    先横竖变换保证第一列全部是1
    竖变换保证其他列1比0多

 

 

862. 和至少为 K 的最短子数组  

  描述:

    

 

 

   思路:前缀和。然后进行双指针判断。

863. 二叉树中所有距离为 K 的结点

  描述:

    

 

 

   思路:对于tartget进行深度优先,。

866. 回文素数

  描述:

    

 

 

   思路:

      

class Solution {
    public int primePalindrome(int N) {
        while (true) {
            if (N == reverse(N) && isPrime(N))
                return N;
            N++;
            if (10_000_000 < N && N < 100_000_000)
                N = 100_000_000;
        }
    }

    public boolean isPrime(int N) {
        if (N < 2) return false;
        int R = (int) Math.sqrt(N);
        for (int d = 2; d <= R; ++d)
            if (N % d == 0) return false;
        return true;
    }

    public int reverse(int N) {
        int ans = 0;
        while (N > 0) {
            ans = 10 * ans + (N % 10);
            N /= 10;
        }
        return ans;
    }
}
View Code

 

869. 重新排序得到 2 的幂

  描述:

    

 

 

   思路:排列组合问题。 。。。回溯算法。

    

class Solution {
    public boolean reorderedPowerOf2(int N) {
        // Build eg. N = 128 -> A = [1, 2, 8]
        String S = Integer.toString(N);
        int[] A = new int[S.length()];
        for (int i = 0; i < S.length(); ++i)
            A[i] = S.charAt(i) - '0';
        return permutations(A, 0);
    }

    // Return true if A represents a valid power of 2
    public boolean isPowerOfTwo(int[] A) {
        if (A[0] == 0) return false;  // no leading zero

        // Build eg. A = [1, 2, 8] -> N = 128
        int N = 0;
        for (int x: A)
            N = 10 * N + x;

        // Remove the largest power of 2
        while (N > 0 && ((N & 1) == 0))
            N >>= 1;

        // Check that there are no other factors besides 2
        return N == 1;
    }

    /**
     * Returns true if some permutation of (A[start], A[start+1], ...)
     * can result in A representing a power of 2.
     */
    public boolean permutations(int[] A, int start) {
        if (start == A.length)
            return isPowerOfTwo(A);

        // Choose some index i from [start, A.length - 1]
        // to be placed into position A[start].
        for (int i = start; i < A.length; ++i) {
            // Place A[start] with value A[i].
            swap(A, start, i);

            // For each such placement of A[start], if a permutation
            // of (A[start+1], A[start+2], ...) can result in A
            // representing a power of 2, return true.
            if (permutations(A, start + 1))
                return true;

            // Restore the array to the state it was in before
            // A[start] was placed with value A[i].
            swap(A, start, i);
        }

        return false;
    }

    public void swap(int[] A, int i, int j) {
        int t = A[i];
        A[i] = A[j];
        A[j] = t;
    }
}
View Code

 

 

870. 优势洗牌

  描述:

    

 

 

   思路:贪心。田忌赛马

    

class Solution {
    public int[] advantageCount(int[] a, int[] b) {
        int n = b.length;
        Arrays.sort(a);
        int[][] pair = new int[n][2];
        for (int i = 0; i < n; i ++)
            pair[i] = new int[]{b[i], i};//把下标保存下来
        Arrays.sort(pair, (x, y)->x[0] - y[0]);

        int[] res = new int[n];
        for (int i = 0, r = n - 1, l = 0; i < n; i ++)//r最大值,l标明最小值;
        {
            if (a[i] <= pair[l][0]) res[pair[r --][1]] = a[i];//要放到原数组对应的位置上
            else res[pair[l ++][1]] = a[i];////要放到原数组对应的位置上
        }
        return res;
    }
}
View Code

 

871. 最低加油次数

  描述:

    

 

 

     

 

 

   思路:

    

class Solution {
    public int minRefuelStops(int target, int startFuel, int[][] stations) {

        if(stations.length == 0)
            return startFuel>=target?0:-1;
        PriorityQueue<Integer>queue = new PriorityQueue<Integer>((o1,o2)->{
            return o2-o1;
        });
        int sum = startFuel;
        int ans = 0;
        for(int i = 0;i < stations.length;i++)
        {
            while(sum < stations[i][0])
            {
                Integer ii = queue.poll();
                if(ii == null)return -1;
                sum += ii;
                ans++;
            }
            queue.offer(stations[i][1]);
        }
        while(sum < target)
            {
                Integer ii = queue.poll();
                if(ii == null)return -1;
                sum += ii;
                ans++;
            }
        return ans;
        
        
    }
    
   
}

 

873. 最长的斐波那契子序列的长度

  描述;
    

 

 

   思路:dp[i][j]:表示以A[i],A[j]结尾的斐波那契数列的最大长度

       

 

 

     

for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
            int diff = A[j] - A[i];
            if (intMap.count(diff)) {
                int index = intMap[diff];
                if (index < i) {
                    dp[i][j] = max(dp[i][j], dp[index][i] + 1);
                }
            }
            MAX = max(MAX, dp[i][j]);
        }
    }
View Code

875. 爱吃香蕉的珂珂

  描述:

    

 

 

   思路:二分。

877. 石子游戏

  描述:
    

 

 

   思路:动态规划。

880. 索引处的解码字符串

  描述:

    

 

 

   思路:栈。

881. 救生艇

  描述:

    

 

 

   思路:贪心。

    

class Solution {
    public int numRescueBoats(int[] people, int limit) {
        Arrays.sort(people);
        int i = 0, j = people.length - 1;
        int ans = 0;

        while (i <= j) {
            ans++;
            if (people[i] + people[j] <= limit)
                i++;
            j--;
        }

        return ans;
    }
}
View Code

886. 可能的二分法

  描述;

    

 

 

   思路:深度优先,标记颜色。。类似于二部图的方法,。

887. 鸡蛋掉落

  描述:

    

 

 

   思路:

def superEggDrop(K: int, N: int):

    memo = dict()
    def dp(K, N) -> int:
        # base case
        if K == 1: return N
        if N == 0: return 0
        # 避免重复计算
        if (K, N) in memo:
            return memo[(K, N)]

        res = float('INF')
        # 穷举所有可能的选择
        for i in range(1, N + 1):
            res = min(res, 
                      max(
                            dp(K, N - i), 
                            dp(K - 1, i - 1)
                         ) + 1
                  )
        # 记入备忘录
        memo[(K, N)] = res
        return res

    return dp(K, N)
View Code

 

 

890. 查找和替换模式

  描述:

    

 

 

   思路:

class Solution {
    public List<String> findAndReplacePattern(String[] words, String pattern) {
        List<String> ans = new ArrayList();
        for (String word: words)
            if (match(word, pattern))
                ans.add(word);
        return ans;
    }

    public boolean match(String word, String pattern) {
        Map<Character, Character> m1 = new HashMap();
        Map<Character, Character> m2 = new HashMap();

        for (int i = 0; i < word.length(); ++i) {
            char w = word.charAt(i);
            char p = pattern.charAt(i);
            if (!m1.containsKey(w)) m1.put(w, p);
            if (!m2.containsKey(p)) m2.put(p, w);
            if (m1.get(w) != p || m2.get(p) != w)
                return false;
        }

        return true;
    }
}
View Code

 

894. 所有可能的满二叉树

  描述:

   

 

   思路:

    Java 首先偶数是不能构成满二叉树的。 思路是把总node数分别左边,根,右边进行递归,如7个node可以分成1,1,5;3,1,5;5,1,1(左,根,右)。 5个node又可以分为1,1,3和3,1,1。 3个node又可以分为1,1,1。 1个node直接返回。

class Solution {
    private HashMap<Integer, List<TreeNode>> hm = null;
    public List<TreeNode> allPossibleFBT(int N) {
        List<TreeNode> rtn = new ArrayList<>();
        if(N % 2 == 0) return rtn;
        if(N == 1) {
            TreeNode root = new TreeNode(0);
            rtn.add(root);
            return rtn;
        }
        if(hm == null) hm = new HashMap<>();
        for(int i = 1; i < N; i += 2) {
            List<TreeNode> left = hm.getOrDefault(i, null);
            if(left == null) {
                left = allPossibleFBT(i);
                hm.put(i, left);
            }
            List<TreeNode> right = hm.getOrDefault(N - 1 - i, null);
            if(right == null) {
                right = allPossibleFBT(N - 1 - i);
                hm.put(N - 1 - i, right);
            }
            for(TreeNode l : left) {
                for(TreeNode r : right) {
                    TreeNode root = new TreeNode(0);
                    root.left = l;
                    root.right = r;
                    rtn.add(root);
                }
            }
        }
        return rtn;
    }
}
View Code

 

posted @ 2020-07-19 20:03  _Meditation  阅读(253)  评论(0编辑  收藏  举报