1. 程式人生 > >邊刷LeetCode邊學習——陣列(一)

邊刷LeetCode邊學習——陣列(一)

陣列相關

基礎知識

Python

在Python中沒有陣列這個說法,類似的有列表(list)元組(tuple)

列表(list)

列表(list)是一種可變的有序集合,可以隨時新增和刪除其中的元素。定義一個列表很簡單:

# 列表中的元素型別可以不相同,也可以是一個 list
list = [0,"java",["又是一個list"]]

使用 len(list)函式可以獲取列表的長度。可以通過索引獲取列表中的元素,索引從0開始;如果索引超出了列表的範圍(0 ≤ i < len(list),i 代表索引)會報一個IndexError錯誤,所以,要確保索引不會越界。列表提供了一些方法操作列表中的元素:

# 向列表末尾追加元素
list.append("新增一個")
# list -> [0,"java",["又是一個list"],"新增一個"]
# 向列表指定位置新增元素
list.insert("Python",2)
# list -> [0,"java","Python",["又是一個list"],"新增一個"]
# 從list末尾刪除一個元素
list.pop()
# list -> [0,"java","Python",["又是一個list"]]
# 從列表指定位置刪除一個元素
list.pop(2)
# list -> [0,"java",["又是一個list"]]
# 改變列表中的某一個元素
list[1] = "Python"
 # list -> [0,"Python",["又是一個list"]]

元組(tuple)

元組(tuple)是一種不可變的有序集合,和列表不同的是,元組的元素一旦確定就不可改變。定義一個元組與列表有些許差別:

# 定義一個有元素的
tup = (1,2,"a",[1,2])
# 定義一個空元組
empty_tup = ()
# 只有一個元素,注意如果不帶“,”會當成一個數字
one_tup = (1,)

同樣,元組和列表一樣,也可以通過索引來訪問元素。

注意:元組的不可變指的是指向不變,如果元組的元素本身是一個可變元素,例如列表,那麼會發現這個列表的元素是可以改變的,但是這個列表的指向並沒有變,所以不能說這個元組變化了。比如 上面定義的元組tup的最後一個元素是一個列表,tup[3][0]=0

這個操作是合法的。

Go

陣列

陣列是一個由固定長度的特定型別元素組成的序列,一個數組可以由零個或多個元素組成。
因為陣列的長度是固定的,因此在Go語言中很少直接使用陣列。和陣列對應的型別是
Slice(切片),它是可以增長和收縮動態序列,slice功能也更靈活

陣列的每個元素可以通過索引下標來訪問,索引下標的範圍是從0開始到陣列長度減1的位
置。內建的len函式將返回陣列中元素的個數。

預設情況下,陣列的每個元素都被初始化為元素型別對應的零值,對於數字型別來說就是0。
我們也可以使用陣列字面值語法用一組值來初始化陣列

var a [3]int // 長度為3的int陣列,預設每個元素值為0
var b = [3]int{1, 2, 3}
fmt.Printf("\t第一個元素:%d", a[0])           // 獲取第一個元素
fmt.Printf("最後一個元素:%d\r\n", a[len(a)-1]) // 獲取最後一個元素 <==> a[2]

在陣列字面值中,如果在陣列的長度位置出現的是“...”省略號,則表示陣列的長度是根據初始
化值的個數來計算。因此,上面b陣列的定義可以簡化為

var b = [...]int{1, 2, 3}

同時,陣列還可以直接指定下標的值例如 c:=[...]int{1:1,99:-1} 這樣將生成一個長度為100的陣列,下表 1 的值為 1,下標 99 的值為 -1,其他均為0.

切片

Slice(切片)代表變長的序列,序列中每個元素都有相同的型別。一個slice型別一般寫作
[]T,其中T代表slice中元素的型別;slice的語法和陣列很像,只是沒有固定長度而已。

一個slice是一個輕量級的資料結構,提供了訪問陣列子序
列(或者全部)元素的功能,而且slice的底層確實引用一個數組物件。一個slice由三個部分
構成:指標、長度和容量。指標指向第一個slice元素對應的底層陣列元素的地址,要注意的
是slice的第一個元素並不一定就是陣列的第一個元素。長度對應slice中元素的數目;長度不
能超過容量,容量一般是從slice的開始位置到底層資料的結尾位置。內建的len和cap函式分
別返回slice的長度和容量。
多個slice之間可以共享底層的資料,並且引用的陣列部分割槽間可能重疊。

演算法題

1、移動零

給定一個數組 nums,編寫一個函式將所有 0 移動到陣列的末尾,同時保持非零元素的相對順序。

示例:

輸入: [0,1,0,3,12]
輸出: [1,3,12,0,0]

說明:

必須在原陣列上操作,不能拷貝額外的陣列。
儘量減少操作次數。

需要用到邏輯判斷和迴圈

Python 邏輯判斷

# 單個條件
if <條件判斷>:
    <執行>
# 多個條件 elif 是 else if 的縮寫
if <條件判斷1>:
    <執行1>
elif <條件判斷2>:
    <執行2>
elif <條件判斷3>:
    <執行3>
else:
    <執行4>

Python 迴圈

# for ... in 迴圈,常用於遍歷可迭代元素
names = ['Michael', 'Bob', 'Tracy']
for name in names:
    print(name)
# while 迴圈
sum = 0
n = 99
while n > 0:
    sum = sum + n
    n = n - 2
print(sum)

Go 邏輯判斷

// 注意 go 語言的 “{” 與 “}” 不可省略
if condition {
    // do something
}

if condition {
    // do something
} else {
    // do something
}

if condition1 {
    // do something
} else if condition2 {
    // do something else
} else {
    // catch-all or default
}

Go 迴圈

// go 中只有 for 迴圈結構
// 基於計數器的迴圈
for i := 0; i < 5; i++ {
    fmt.Printf("This is the %d iteration\n", i)
}

// 基於條件的迴圈
for i >= 0 {
    i = i - 1
    fmt.Printf("The variable i is now: %d\n", i)
}

示例程式碼:

// Java 程式碼
import java.util.Arrays;

/**
 * MoveZero
 */
public class MoveZero {

    public static void main(String[] args) {
        MoveZero mZero = new MoveZero();
        mZero.moveZeroes(new int[]{0,1,0,3,12});
    }

    public void moveZeroes(int[] nums) {
        // soulution1(nums);
        soulution2(nums);
        System.out.print(Arrays.toString(nums));
    }
    /**
     * 該方法思路是把為 0 的數往後移,遇到了不為0的則交換位置,繼續下一位的移動
     */
    public void soulution1(int[] nums){
        int len = nums.length;
        for (int i = 0; i < len; i++) {
            // 如果是0,則往後移,遇到非 0 的就結束移動
            if(nums[i]==0){
                for (int j = i+1; j < nums.length; j++) {
                    if(nums[j]!=0){
                        int temp = nums[j];
                        nums[j]=nums[i];
                        nums[i]=temp;
                        break;
                    }
                }
            }
        }
    }

    /**
     * 該方法思路是把不為 0 的往遷移,全部移動完之後,剩下的都是0;
     * 相比較第一種方法,迴圈次數較少
     */
    public void soulution2(int[] nums){
        int i = 0;
        // 把不是0的往前移動,i就是非0的個數
        for (int j = 0; j < nums.length; j++){
            if (nums[j] != 0) {
                nums[i++] = nums[j];
            }
        }
        // 從i開始剩下的都是 0
        for (int k = i; k < nums.length; k++){
            nums[k] = 0;
        }
    }

    public void soulution3(int[] nums) {
        int s = 0;
        int f = 0;
        while (f < nums.length) {
            if (nums[f] != 0) {
                int temp = nums[f];
                nums[f] = nums[s];
                nums[s] = temp;
                s++;
            }
            f++;
        }
    }
}
# Python
class MoveZero(object):
    def __init__(self):
        print("移動零1")

    def moveZeroes(self,nums):
        # self.solution1(nums)
        # self.solution2(nums)
        self.solution3(nums)
        print(nums)

    def solution1(self,nums):
        i = 0
        for v in nums:
            if v == 0:
                j = i+1
                while j < len(nums):
                    if nums[j] != 0:
                        temp = nums[j]
                        nums[j] = v
                        nums[i] = temp
                        break
                    j+=1
            i+=1

    def solution2(self,nums):
        i = 0
        for v in nums:
            if v != 0:
                nums[i]=v
                i+=1
        while i < len(nums):
            nums[i]=0
            i+=1

    def solution3(self,nums):
        i = 0
        j = 0
        while i < len(nums):
            if nums[i] != 0:
                temp = nums[i]
                nums[i] = nums[j]
                nums[j] = temp
                j+=1
            i+=1

moveZero = MoveZero()
moveZero.moveZeroes([1,0,3,0,5])
package main

import (
    "fmt"
)

func main() {
    nusm := [5]int{0, 3, 0, 5, 2}
    // 從陣列獲取切片
    moveZero(nusm[:])
}

func moveZero(nums []int) {
    // solution1(nums)
    // solution2(nums)
    solution3(nums)
    fmt.Print(nums)
}

func solution1(nums []int) {
    for i, v := range nums {
        if v == 0 {
            for j := i + 1; j < len(nums); j++ {
                if nums[j] != 0 {
                    temp := nums[j]
                    nums[j] = nums[i]
                    nums[i] = temp
                    break
                }
            }
        }
    }
}

func solution2(nums []int) {
    i := 0
    for _, v := range nums {
        if v != 0 {
            nums[i] = v
            i++
        }
    }
    for j := i; j < len(nums); j++ {
        nums[j] = 0
    }
}

func solution3(nums []int) {
    s := 0
    f := 0
    for f < len(nums) {

        if nums[f] != 0 {
            nums[s], nums[f] = nums[f], nums[s]
            s++
        }
        f++

    }
}