【LeetCode】初級演算法:陣列

widiot1發表於2018-05-09

題目可以在LeetCode檢視

1. 從排序陣列中刪除重複項

用時:11ms

class Solution {
    public int removeDuplicates(int[] nums) {
        int length=nums.length;
        int count=0,remove=0;
        // 如果陣列長度為1,直接返回
        if(length==1){
            ++count;
        }else{
            // 直接將陣列後面不同的元素移動到前面
            for(int i=1;i<length-remove;i++){
                if(nums[i]!=nums[count]){
                    nums[++count]=nums[i];
                }
            }
            ++count;
        }
        return count;
    }
}

2. 買賣股票的最佳時機 II

用時:1ms

class Solution {
    public int maxProfit(int[] prices) {
        int profit=0;
        boolean buy=false;
        for(int i=0;i<prices.length-1;i++){
            // 如果還沒買,並且明天股價上漲,則今天買
            // 否則再等一天
            if(!buy&&prices[i]<prices[i+1]){
                profit-=prices[i];
                buy=true;
            }else if(buy){
                // 已經買了
                // 如果明天股價上漲或不變,則再等等看還漲不漲
                // 如果明天股價下跌,則今天賣
                if(prices[i]>prices[i+1]){
                    profit+=prices[i];
                    buy=false;
                }
            }
        }
        // 如果已經買了,倒數第二天沒有賣,則最後一天直接賣
        if(buy){
            profit+=prices[prices.length-1];
        }
        return profit;
    }
}

3. 旋轉陣列

用時:1ms

class Solution {
    public void rotate(int[] nums, int k) {
        // 方法1用時:128ms
        // int len=nums.length;
        // int temp;
        // // 移動輪次
        // for(int i=0;i<k;i++){
        //     temp=nums[len-1];
        //     // 每次將最後一個元素作為空位,左邊元素右移,再把最後一個元素放在第一個位置
        //     for(int j=len-1;j>0;j--){
        //         nums[j]=nums[j-1];
        //     }
        //     nums[0]=temp;
        // }
     
        
        int len=nums.length;
        k%=len;
        // 先旋轉整個陣列,再分別旋轉兩個子陣列
        reverse(nums,0,len-1);
        reverse(nums,0,k-1);
        reverse(nums,k,len-1);
    }
    
    private void reverse(int[] nums,int start,int end){
        int temp;
        while(start<end){
            temp=nums[start];
            nums[start++]=nums[end];
            nums[end--]=temp;
        }
    }
}

4. 存在重複

用時:5ms

class Solution {
    public boolean containsDuplicate(int[] nums) {
        int len=nums.length;
        if(len>1){
            // 從排序陣列中找到兩個相同的元素
            Arrays.sort(nums);
            for(int i=0;i<leng-1;++i){
                if(nums[i]==nums[i+1]){
                    return true;
                }
            }
        }
        return false;
    }
}

5. 只出現一次的數字

用時:7ms

class Solution {
    public int singleNumber(int[] nums) {
        int len=nums.length;
        int i=0;
        if(len>1){
            // 從排序陣列中直接找到一組不同的元素
            Arrays.sort(nums);
            for(i=0;i<len-1;i+=2){
                if(nums[i]!=nums[i+1]){
                    return nums[i];
                }
            }
        }
        return nums[i];
    }
}

6. 兩個陣列的交集 II

用時:4ms

class Solution {
    public int[] intersect(int[] nums1, int[] nums2) {
        int len1=nums1.length,len2=nums2.length;
        int lenMin=Math.min(len1,len2);
        int[] intersection=new int[lenMin];
        int count=0;
        if(lenMin>0){
            // 從兩個排序陣列中找到相同數的位置
            Arrays.sort(nums1);
            Arrays.sort(nums2);
            int i=0,j=0;
            while(i<len1&&j<len2){
                if(nums1[i]<nums2[j]){
                    ++i;
                }else if(nums1[i]>nums2[j]){
                    ++j;
                }else{
                    intersection[count++]=nums1[i];
                    ++i;
                    ++j;
                }
            }
        }
        return Arrays.copyOfRange(intersection,0,count);
    }
}

7. 加一

用時:0ms

class Solution {
    public int[] plusOne(int[] digits) {
        int len=digits.length;
        int[] newDigits=new int[len+1];
        newDigits[0]=0;
        
        // 從第一位開始加上進位
        int sum,carry=1;
        for(int i=len-1;i>=0;--i){
            sum=digits[i]+carry;
            if(sum<10){
                newDigits[i+1]=sum;
                carry=0;
            }else{
                newDigits[i+1]=sum%10;
                carry=1;
            }
        }
        newDigits[0]+=carry;

        if(newDigits[0]==0){
            return Arrays.copyOfRange(newDigits,1,len+1);
        }else{
            return newDigits;
        }
    }
}

8. 移動零

用時:2ms

class Solution {
    public void moveZeroes(int[] nums) {
        int len=nums.length;
        int count=0;
        // 先將所有不為0的數前移
        // 並統計不為0的數的數量
        for(int i=0;i<len;++i){
            if(nums[i]!=0){
                nums[count++]=nums[i];
            }
        }
        
        // 將剩下的數置為0
        while(count<len){
            nums[count++]=0;
        }
    }
}

9. 兩數之和

用時:8ms

class Solution {
    public int[] twoSum(int[] nums, int target) {
        int len=nums.length;
        int[] plus=new int[2];
        int temp;
        // 用HashMap記錄兩個加數中的一個
        // 然後用和去減當前數,看HashMap中是否存在差值
        HashMap<Integer,Integer> minus=new HashMap<>();
        for(int i=0;i<len;++i){
            temp=target-nums[i];
            if(minus.containsKey(temp)){
                plus[0]=minus.get(temp);
                plus[1]=i;
                return plus;
            }
            minus.put(nums[i],i);
        }
        
        return plus;
    }
}

10. 有效的數獨

用時:36ms

class Solution {
    public boolean isValidSudoku(char[][] board) {
        Set<Character> rowDigits=new HashSet<>();
        Set<Character> colDigits=new HashSet<>();
        Character dot=new Character('.');
        
        // 判斷行和列
        int i,j,m,n;
        for(i=0;i<9;++i){
            for(j=0;j<9;++j){
                if(!dot.equals(board[i][j])&&!rowDigits.add(board[i][j])){
                    return false;
                }
                if(!dot.equals(board[j][i])&&!colDigits.add(board[j][i])){
                    return false;
                }
            }
            rowDigits.clear();
            colDigits.clear();
        }
        
        // 判斷九宮格
        for(i=0;i<9;i+=3){ // 行
            for(j=0;j<9;j+=3){ // 列
                for(m=0;m<3;++m){ // 九宮格
                    for(n=0;n<3;++n){
                        if(!dot.equals(board[i+m][j+n])&&!rowDigits.add(board[i+m][j+n])){
                            return false;
                        }
                    }
                }
                rowDigits.clear();
            }
        }

        return true;
    }
}

11. 旋轉影像

用時:2ms

class Solution {
    public void rotate(int[][] matrix) {
        int len=matrix.length;
        int n=len-1;
        int rounds=(len+1)/2;
        int move=len;
        int [][] corner=new int[4][2];
        int temp;
        
        for(int i=0;i<rounds;++i){
            corner[0][0]=i;
            corner[0][1]=i;
            corner[1][0]=i;
            corner[1][1]=n-i;
            corner[2][0]=n-i;
            corner[2][1]=n-i;
            corner[3][0]=n-i;
            corner[3][1]=i;
            
            for(int j=0;j<move-1;++j){
                temp=matrix[corner[0][0]][corner[0][1]];
                matrix[corner[0][0]][corner[0][1]]=matrix[corner[3][0]][corner[3][1]];
                matrix[corner[3][0]][corner[3][1]]=matrix[corner[2][0]][corner[2][1]];
                matrix[corner[2][0]][corner[2][1]]=matrix[corner[1][0]][corner[1][1]];
                matrix[corner[1][0]][corner[1][1]]=temp;
                
                ++corner[0][0];
                --corner[1][1];
                --corner[2][0];
                ++corner[3][1];
            }
            
            move-=2;
        }
    }
}

相關文章