1. 程式人生 > 實用技巧 >【總結】1.陣列

【總結】1.陣列

一.陣列

1.稀疏陣列

當一個數組大部分元素為0,或者為同一個值的陣列時,可以用稀疏陣列來儲存該陣列
(1)記錄陣列有幾行幾列,有多少個不同的值
(2)把具有不同值的元素的行列值記錄在一個小規模的陣列中

//二維陣列轉稀疏陣列
    private static int[][] parseSparseArray(int[][] array){
        //得到非0元素個數
        int sum = 0;
        int len = array.length;
        int height = array[0].length;
        for (int i = 0; i < len; i++){
            for (int j = 0; j < height; j++){
                if (array[i][j] != 0 ){
                    sum += 1;
                }
            }
        }
        int[][] result = new int[sum + 1][3];
        //為稀疏陣列第一行賦值
        result[0][0] = len;
        result[0][1] = height;
        result[0][2] = sum;
        //為剩餘行賦值
        int flag = 1;
        for (int i = 0; i < len; i++){
            for (int j = 0; j < height; j++){
                if (array[i][j] != 0){
                    result[flag][0] = i;
                    result[flag][1] = j;
                    result[flag][2] = array[i][j];
                    flag++;
                }
            }
        }
        return result;
    }

2.陣列實現佇列

public class ArrayParse2Queue {
    public ArrayParse2Queue(int maxSize){
        queue = new int[maxSize];
        front = -1; //指向第一個元素的前一個元素
        rear = -1; //指向最後一個元素
        this.maxSize = maxSize;
    }

    //判滿
    public boolean isFull(){
        return rear == maxSize -1;
    }
    //判空
    public boolean isempty(){
        return rear == front;
    }
    //入隊
    public void push(int a){
        if (isFull()){
            throw new RuntimeException("佇列已滿");
        }
        queue[++rear] = a;
    }
    //出隊
    public int pop(){
        if (isempty()){
            throw new RuntimeException("佇列已空");
        }
        int temp = queue[front+1];
        front ++;
        return temp;
    }
    //列印佇列
    public void printQueue(){
        for (int i = front+1; i <= rear; i++){
            System.out.print(queue[i] + " ");
        }
    }
}

3.陣列實現環形佇列

由於在用陣列實現佇列的時候,佇列有元素出列,front就向後移動,所以佇列前面的空間就空了出來。當rear移動到LENGTH時,再入隊會發生假溢位,也就是說實際上我們開闢的陣列還有剩餘空間,卻因為rear越界表現為溢位,
為了更合理的利用空間,人們想了一個辦法:將佇列的首尾相連線。這樣當rear移動到LENGTH時,會再從0開始迴圈
那當什麼時候佇列滿呢?當rear等於front的時候。可是佇列為空的時候也是同樣的條件,那不就沒法判斷了嗎?犧牲一個儲存空間,front前面不存資料,當rear在front前面的時候就是滿了(尾在頭前就是滿了)

隊空條件:front == rear

隊滿條件:(rear+1) %QueueSize == front

佇列長度:(rear—front + QueueSize) % QueueSize
(當rear > front時,此時佇列的長度為rear—front。但當rear < front時,佇列長度分為兩段,一段是QueueSize-front,另一段是0 + rear,加在一起,佇列長度為rear-front + QueueSize,)

public class CircleQueue {
    
    int front;
    int rear;
    int[] queue;
    int maxSize;

    public CircleQueue(int maxSize){
        queue = new int[maxSize];
        front = 0; //指向第一個元素的前一個元素
        rear = 0; //指向最後一個元素
        this.maxSize = maxSize;
    }

    //判滿
    public boolean isFull(){
        return (rear + 1) % maxSize == front;
    }
    //判空
    public boolean isempty(){
        return rear == front;
    }
    //入隊
    public void push(int a){
        if (isFull()){
            throw new RuntimeException("佇列已滿");
        }
        queue[rear] = a;
        rear = (rear + 1) % maxSize;
    }
    //出隊
    public int pop(){
        if (isempty()){
            throw new RuntimeException("佇列已空");
        }
        int temp = queue[front];
        front = (front + 1) % maxSize;
        return temp;
    }
    //列印佇列
    public void printQueue(){
        for (int i = front; i < front + size(); i++){
            System.out.print(queue[i] + " ");
        }
    }
    //佇列長度
    public int size(){
        return (rear + maxSize -front) % maxSize;
    }
}

4.leetcode-1 兩數之和

給定一個整數陣列 nums 和一個目標值 target,請你在該陣列中找出和為目標值的那 兩個 整數,並返回他們的陣列下標
你可以假設每種輸入只會對應一個答案。但是,你不能重複利用這個陣列中同樣的元素

示例:給定 nums = [2, 7, 11, 15], target = 9
因為 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
(1)暴力法

class Solution {
    public int[] twoSum(int[] nums, int target) {
        for (int i = 0; i < nums.length; i++) {
            for (int j = i + 1; j < nums.length; j++) {
                if (nums[j] == target - nums[i]) {
                    return new int[] { i, j };
                }
            }
        }
        throw new IllegalArgumentException("No two sum solution");
    }
}

(2)雜湊表
在進行迭代並將元素插入到表中的同時,我們還會回過頭來檢查表中是否已經存在當前元素所對應的目標元素。如果它存在,那我們已經找到了對應解,並立即將其返回

class Solution {
    public int[] twoSum(int[] nums, int target) {
        Map<Integer, Integer> map = new HashMap<>();
        for (int i = 0; i < nums.length; i++) {
            int complement = target - nums[i];
            if (map.containsKey(complement)) {
                return new int[] { map.get(complement), i };
            }
            map.put(nums[i], i);
        }
        throw new IllegalArgumentException("No two sum solution");
    }
}