LeetCode总结整型数组类题目

寻找唯一的单个数

题目:https://leetcode.com/problems/single-number/

武器:利用map计算次数,线性时间。但是需要O(n)存储空间

结果:未通过

新武器:XOR操作

异或的运算方法是一个二进制运算:

1^1=0

0^0=0

1^0=1

0^1=1

两者相等为0,不等为1.

(1) a ^ b = b ^ a;
(2) (a ^ b) ^ c = a ^ (b ^ c);
(3) a ^ a = 0, a ^ 0 = a;
the ^ means XOR.

a ^ b ^ b ^ c ^ c = a ^ 0 ^ 0 = a,只有一个单个元素,所以最后异或的结果就是单个数字。

class Solution {
    public int singleNumber(int[] nums) {
       int result=0;
        for(int i=0;i

移动0到数组尾部

题目:https://leetcode.com/problems/move-zeroes/

武器: 两个指针,基于交换。但是比较麻烦。简单思路是直接覆盖

结果:未通过

新武器:如果是0,没有必要交换,直接覆盖,最后空余位置直接添加0就可以。

本次用自己的解法通过:

class Solution {
    public void moveZeroes(int[] nums) {
        int i=0;
        int j=0;
        int n=nums.length;
        while(i

寻找占据数组大多数的元素

题目:https://leetcode.com/problems/majority-element/

武器: Hashmap统计次数

结果:一次通过

是否包含重复元素

题目:https://leetcode.com/problems/contains-duplicate/

武器: hashmap统计次数

结果:一次通过

寻找缺少的一个元素

题目:https://leetcode.com/problems/missing-number/

武器: hashset

结果:未通过。

思路对,忽略了这个题目中,长度就是最后一个数字这个细节。遍历数组一遍存入set,循环<=n,数组的长度,判断是否每个元素都在set中

股票买卖I

题目:https://leetcode.com/problems/best-time-to-buy-and-sell-stock/

武器:分析结果的关键,本来用dp,没有找到转换方程。后来发现对于当前元素,找到当前最小值,两者相减法,就是最大利润。如果是负数,max后取0也实用。当时应该是参考别人的算法写的,这次自己分析问题能力的确提高很多

结果:超过预期通过

Two Sum

题目:https://leetcode.com/problems/two-sum/

武器: HashMap(二次,一次都可以,最好写成一次),另一个武器,for循环过程中其实就是二分查找问题,先排序,然后for循环,寻找另外一个元素。或者排序后两个指针一个头,一个尾部,计算和,根据和与target的关系,移动low或者high,因为有序,我们可以这么做

新修改:两次for循环不可以,因为如果有重复元素,map会覆盖,所以就是一次for循环,放入元素和位置,下面继续判断left是否存在,如果存在就返回两个索引,这样即时第二个和第一个元素相同,也不会覆盖

结果:自己思考修正原来错误完美通过

从有序数组移除重复元素

题目:https://leetcode.com/problems/remove-duplicates-from-sorted-array/ 要求空间复杂度O(1)

武器:分析移除方法,发现不同元素直接重新写入当前数组,不需要额外新建

结果:通过

数组右移动k个元素

题目:https://leetcode.com/problems/rotate-array/

武器:有移效果分解,其实先反转整个数组,然后反转前k个,然后反转后k个,二维矩阵也有这个方法

结果:未通过,思路没有

数组除自身外的乘积

题目:https://leetcode.com/problems/product-of-array-except-self/

武器:除自身,因为不让用除法计算,那么可以这么理解,左侧乘积*右侧乘积=当前值除自身的乘积

结果:思路当时并没有理解透彻

Top K频率元素

题目:https://leetcode.com/problems/top-k-frequent-elements/  must be better than O(n log n)

武器:1. TreeMap排序统计频率,因为treemap可以根据频率排序,频率为key,时间复杂度不是线性的

           2. Hashmap统计频率,然后频率为value,利用桶排序就可以,新建数组,根据频率决定索引,每个数组的元素是list,负责存储改频率的所有元素,然后倒序遍历数组就是从高频到低频。利用空间换取时间。

结果:基本通过

两个注意:第一,桶排序的时候的数组的元素为list类型,第二top k最后计算的时候,相同的也算入个数,不是指不同的。

 4Sum II

题目:https://leetcode.com/problems/4sum-ii/

武器 Hashmap

结果:思路正确,第一次把AB存入map,value是个数,开始还想用set存储,第二个CD的时候判断sum*-1在map中的个数就可以,不是判断是否存在,我思路想的是是否存在。

Find the Duplicate Number

题目:https://leetcode.com/problems/find-the-duplicate-number/

武器: 时间复杂度优于O(n2),空间复杂度是O(1)。之前一道题目是求唯一不重复的,利用异或操作可以。因为异或操作a^a=0,b^0=b.最后异或的结果就是不重复的数字。这道题目,因为空间复杂度所以不能利用map计算,利用快速排序算法,时间复杂度满足,而且关键是空间复杂度也满足。排序后重复的数字就挨着了。

结果:通过,但是快速排序的核心代码不要直接用low和high,因为移动后,在交换轴元素和low移动后的位置的时候,已经没有轴元素的指针了,需要i=low,j=high,然后移动i和j处理就可以。另外key元素第一次是nums[0]但是递归代码里面应该是nums[low],始终是最低位元素。

Kth Largest Element in an Array

快速排序代码有几个错误点,注意一下:

LeetCode总结整型数组类题目_第1张图片

 Container With Most Water

题目:https://leetcode.com/problems/container-with-most-water/

武器:两个指针,其实就是面积问题,max=Math.max(max,Math.min(nums[p],nums[q])*(q-p)),需要注意的是指针移动不是直接p++,q--。而是谁小移动谁,这样才能保证找到最大的。

结果:部分通过

Sort Colors

题目:https://leetcode.com/problems/sort-colors/

武器:1.桶排序,因为只有0 1 2 三个值,但是空间复杂度不符合要求

           2  快速排序

结果:通过

Find Peak Element

题目:https://leetcode.com/problems/find-peak-element/

武器:折半查找。根据时间复杂度是logn,想起来用折半,但是感觉不是有序的,不行。其实可以,因为比较条件不是是否相等,而是始终超上升的方向走,结果只有两种,第一是一直上升,第二是下降。无论那种我们都能找到一个峰值

if(nums[mid]>nums[mid+1]){

   high=mid;

}

 else{

   low=mid+1;

}

Perfect Squares

题目:https://leetcode.com/problems/perfect-squares/

武器:动态规划,我已经成功破解关键方程 dp[i]=Math.min(dp[i-1]+1,dp[i-4]+1,dp[i-9]+1,......),一直到i的平方根。但是有点问题是我忘记了外层循环for(i=1;i<=n;i++),因为这样方程需要的中间值必须有外层循环。另外一个忽略点,dp默认都填充最大值方便进行min比较。

class Solution {
    public int numSquares(int n) {
        int[]  dp=new int[n+1];
        for(int k=1;k<=n;k++){
            dp[k]=Integer.MAX_VALUE;
        }
        for(int i=1;i<=n;i++){
             int sqrt=(int)Math.sqrt(i);
            for(int j=1;j<=sqrt;j++){
               dp[i]=Math.min(dp[i],1+dp[i-(j*j)]);      
             } 
        }
       
        return dp[n];
    }
}

Longest Increasing Subsequence

题目:https://leetcode.com/problems/longest-increasing-subsequence/

武器:动态规划

结果:两次外层循环,因为不是一定要连续,所以dp[i]定义为小于nums[i]的元素的dp[j]最大值,注意不是小于nums[i]的元素个数,因为可能不是一直增长的。思路基本正确,注意点失误了

Letter Combinations of a Phone Number

题目:https://leetcode.com/problems/letter-combinations-of-a-phone-number/

武器:队列LinkedList先入一个空字符串,保证while条件可以开始。然后queue负责保存中间结果,队列中取出元素与下一个组合结果,然后入队列,直到队列中peek的队首元素长度与digits长度一样,表示组合完毕。注意:mapping关系可以用数组,不需要用map

结果:思路遗忘了

         String[] mapping = new String[]{"0", "1", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
        //添加一个空元素,保证第一个字符串入队
        res.add("");
        while (res.peek().length() != digits.length()) {
            String removed = res.remove();
            String toAddElement = mapping[digits.charAt(removed.length()) - '0'];
            for (char ch : toAddElement.toCharArray()) {
                res.addLast(removed + ch);
            }
        }

Course Schedule

题目:https://leetcode.com/problems/course-schedule-ii/

题目:https://leetcode.com/problems/course-schedule

武器:DAG是否有环的问题。利用二维数组角度去解决。步骤如下

1. 循环数组计算各个值的入度,存入indegree数组

2 从入度为0元素开始。寻找入度为0的值加入队列。

3 循环从队列取出元素,直到队列为空。取出元素后,加入结果集,然后循环数组,判断源端是此元素的入度减去1,相当于取出这个右向链接。此时如果入度为0,加入队列

4 最后队列为空的时候,结果集的size如果为所有元素就是无环的,反之有环。

你可能感兴趣的:(架构设计,Leetcode算法)