mirror of
				https://github.com/krahets/hello-algo.git
				synced 2025-11-04 06:07:20 +08:00 
			
		
		
		
	Merge branch 'master' of github.com:krahets/hello-algo
This commit is contained in:
		
							
								
								
									
										112
									
								
								codes/c/chapter_array_and_linkedlist/array.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								codes/c/chapter_array_and_linkedlist/array.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,112 @@
 | 
			
		||||
/*
 | 
			
		||||
 * File: array.c
 | 
			
		||||
 * Created Time: 2022-12-20
 | 
			
		||||
 * Author: MolDuM (moldum@163.com)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "../include/include.h"
 | 
			
		||||
 | 
			
		||||
/* 随机返回一个数组元素 */
 | 
			
		||||
int randomAccess(int* nums, int size) {
 | 
			
		||||
    // 在区间 [0, size) 中随机抽取一个数字
 | 
			
		||||
    int randomIndex = rand() % size;
 | 
			
		||||
    // 获取并返回随机元素
 | 
			
		||||
    int randomNum = nums[randomIndex];
 | 
			
		||||
    return randomNum;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* 扩展数组长度 */
 | 
			
		||||
int* extend(int* nums, int size, int enlarge) {
 | 
			
		||||
    // 初始化一个扩展长度后的数组
 | 
			
		||||
    int* res = (int *)malloc(sizeof(int) * (size + enlarge));
 | 
			
		||||
    // 将原数组中的所有元素复制到新数组
 | 
			
		||||
    for (int i = 0; i < size; i++) {
 | 
			
		||||
        res[i] = nums[i];
 | 
			
		||||
    }
 | 
			
		||||
    // 初始化扩展后的空间
 | 
			
		||||
    for (int i = size; i < size + enlarge; i++) {
 | 
			
		||||
        res[i] = 0;
 | 
			
		||||
    }
 | 
			
		||||
    // 返回扩展后的新数组
 | 
			
		||||
    return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* 在数组的索引 index 处插入元素 num */
 | 
			
		||||
void insert(int* nums, int size, int num, int index) {
 | 
			
		||||
    // 把索引 index 以及之后的所有元素向后移动一位
 | 
			
		||||
    for (int i = size - 1; i > index; i--) {
 | 
			
		||||
        nums[i] = nums[i - 1];
 | 
			
		||||
    }
 | 
			
		||||
    // 将 num 赋给 index 处元素
 | 
			
		||||
    nums[index] = num;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* 删除索引 index 处元素 */
 | 
			
		||||
void removeItem(int* nums, int size, int index) {
 | 
			
		||||
    // 把索引 index 之后的所有元素向前移动一位
 | 
			
		||||
    for (int i = index; i < size - 1; i++) {
 | 
			
		||||
        nums[i] = nums[i + 1];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* 遍历数组 */
 | 
			
		||||
void traverse(int* nums, int size) {
 | 
			
		||||
    int count = 0;
 | 
			
		||||
    // 通过索引遍历数组
 | 
			
		||||
    for (int i = 0; i < size; i++) {
 | 
			
		||||
        count++;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* 在数组中查找指定元素 */
 | 
			
		||||
int find(int* nums, int size, int target) {
 | 
			
		||||
    for (int i = 0; i < size; i++) {
 | 
			
		||||
        if (nums[i] == target)
 | 
			
		||||
            return i;
 | 
			
		||||
    }
 | 
			
		||||
    return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Driver Code */
 | 
			
		||||
int main() {
 | 
			
		||||
    /* 初始化数组 */
 | 
			
		||||
    int size = 5;
 | 
			
		||||
    int arr[5];
 | 
			
		||||
    printf("数组 arr = ");
 | 
			
		||||
    printArray(arr, size);
 | 
			
		||||
 | 
			
		||||
    int nums[5] = { 1, 3, 2, 5, 4 };
 | 
			
		||||
    printf("数组 nums = ");
 | 
			
		||||
    printArray(nums, size);
 | 
			
		||||
    
 | 
			
		||||
    /* 随机访问 */
 | 
			
		||||
    int randomNum = randomAccess(nums, size);
 | 
			
		||||
    printf("在 nums 中获取随机元素 %d", randomNum);
 | 
			
		||||
    
 | 
			
		||||
    /* 长度扩展 */
 | 
			
		||||
    int enlarge = 3;
 | 
			
		||||
    int* res = extend(nums, size, enlarge);
 | 
			
		||||
    size += enlarge;
 | 
			
		||||
    printf("将数组长度扩展至 8 ,得到 nums = ");
 | 
			
		||||
    printArray(res, size);
 | 
			
		||||
    
 | 
			
		||||
    /* 插入元素 */
 | 
			
		||||
    insert(res, size, 6, 3);
 | 
			
		||||
    printf("在索引 3 处插入数字 6 ,得到 nums = ");
 | 
			
		||||
    printArray(res, size);
 | 
			
		||||
 | 
			
		||||
    /* 删除元素 */
 | 
			
		||||
    removeItem(res, size, 2);
 | 
			
		||||
    printf("删除索引 2 处的元素,得到 nums = ");
 | 
			
		||||
    printArray(res, size);
 | 
			
		||||
    
 | 
			
		||||
    /* 遍历数组 */
 | 
			
		||||
    traverse(res, size);
 | 
			
		||||
    
 | 
			
		||||
    /* 查找元素 */
 | 
			
		||||
    int index = find(res, size, 3);
 | 
			
		||||
    printf("在 res 中查找元素 3 ,得到索引 = %d\n", index);
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										30
									
								
								codes/c/include/PrintUtil.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								codes/c/include/PrintUtil.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,30 @@
 | 
			
		||||
/*
 | 
			
		||||
 * File: PrintUtil.h
 | 
			
		||||
 * Created Time: 2022-12-21
 | 
			
		||||
 * Author: MolDum (moldum@163.com)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
// #include "ListNode.h"
 | 
			
		||||
// #include "TreeNode.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Print an Array
 | 
			
		||||
 * 
 | 
			
		||||
 * @param arr 
 | 
			
		||||
 * @param n 
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
static void printArray(int* arr, int n)
 | 
			
		||||
{
 | 
			
		||||
    printf("[");
 | 
			
		||||
    for (int i = 0; i < n - 1; i++) {
 | 
			
		||||
        printf("%d, ", arr[i]);
 | 
			
		||||
    }
 | 
			
		||||
    printf("%d]\n", arr[n-1]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,2 +1,12 @@
 | 
			
		||||
/*
 | 
			
		||||
 * File: include.h
 | 
			
		||||
 * Created Time: 2022-12-20
 | 
			
		||||
 * Author: MolDuM (moldum@163.com)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
 | 
			
		||||
#include "PrintUtil.h"
 | 
			
		||||
 | 
			
		||||
@ -8,11 +8,13 @@ let package = Package(
 | 
			
		||||
        .executable(name: "time_complexity", targets: ["time_complexity"]),
 | 
			
		||||
        .executable(name: "worst_best_time_complexity", targets: ["worst_best_time_complexity"]),
 | 
			
		||||
        .executable(name: "space_complexity", targets: ["space_complexity"]),
 | 
			
		||||
        .executable(name: "leetcode_two_sum", targets: ["leetcode_two_sum"]),
 | 
			
		||||
    ],
 | 
			
		||||
    targets: [
 | 
			
		||||
        .target(name: "utils", path: "utils"),
 | 
			
		||||
        .executableTarget(name: "time_complexity", path: "chapter_computational_complexity", sources: ["time_complexity.swift"]),
 | 
			
		||||
        .executableTarget(name: "worst_best_time_complexity", path: "chapter_computational_complexity", sources: ["worst_best_time_complexity.swift"]),
 | 
			
		||||
        .executableTarget(name: "space_complexity", dependencies: ["utils"], path: "chapter_computational_complexity", sources: ["space_complexity.swift"]),
 | 
			
		||||
        .executableTarget(name: "leetcode_two_sum", path: "chapter_computational_complexity", sources: ["leetcode_two_sum.swift"]),
 | 
			
		||||
    ]
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,46 @@
 | 
			
		||||
/*
 | 
			
		||||
 * File: leetcode_two_sum.swift
 | 
			
		||||
 * Created Time: 2023-01-03
 | 
			
		||||
 * Author: nuomi1 (nuomi1@qq.com)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
func twoSumBruteForce(nums: [Int], target: Int) -> [Int] {
 | 
			
		||||
    // 两层循环,时间复杂度 O(n^2)
 | 
			
		||||
    for i in nums.indices.dropLast() {
 | 
			
		||||
        for j in nums.indices.dropFirst(i + 1) {
 | 
			
		||||
            if nums[i] + nums[j] == target {
 | 
			
		||||
                return [i, j]
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return [0]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func twoSumHashTable(nums: [Int], target: Int) -> [Int] {
 | 
			
		||||
    // 辅助哈希表,空间复杂度 O(n)
 | 
			
		||||
    var dic: [Int: Int] = [:]
 | 
			
		||||
    // 单层循环,时间复杂度 O(n)
 | 
			
		||||
    for i in nums.indices {
 | 
			
		||||
        if let j = dic[target - nums[i]] {
 | 
			
		||||
            return [j, i]
 | 
			
		||||
        }
 | 
			
		||||
        dic[nums[i]] = i
 | 
			
		||||
    }
 | 
			
		||||
    return [0]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@main
 | 
			
		||||
enum LeetcodeTwoSum {
 | 
			
		||||
    static func main() {
 | 
			
		||||
        // ======= Test Case =======
 | 
			
		||||
        let nums = [2, 7, 11, 15]
 | 
			
		||||
        let target = 9
 | 
			
		||||
        // ====== Driver Code ======
 | 
			
		||||
        // 方法一
 | 
			
		||||
        var res = twoSumBruteForce(nums: nums, target: target)
 | 
			
		||||
        print("方法一 res = \(res)")
 | 
			
		||||
        // 方法二
 | 
			
		||||
        res = twoSumHashTable(nums: nums, target: target)
 | 
			
		||||
        print("方法二 res = \(res)")
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -149,6 +149,22 @@ comments: true
 | 
			
		||||
    }
 | 
			
		||||
    ```
 | 
			
		||||
 | 
			
		||||
=== "Swift"
 | 
			
		||||
 | 
			
		||||
    ```swift title="leetcode_two_sum.swift"
 | 
			
		||||
    func twoSumBruteForce(nums: [Int], target: Int) -> [Int] {
 | 
			
		||||
        // 两层循环,时间复杂度 O(n^2)
 | 
			
		||||
        for i in nums.indices.dropLast() {
 | 
			
		||||
            for j in nums.indices.dropFirst(i + 1) {
 | 
			
		||||
                if nums[i] + nums[j] == target {
 | 
			
		||||
                    return [i, j]
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return [0]
 | 
			
		||||
    }
 | 
			
		||||
    ```
 | 
			
		||||
 | 
			
		||||
### 方法二:辅助哈希表
 | 
			
		||||
 | 
			
		||||
时间复杂度 $O(N)$ ,空间复杂度 $O(N)$ ,属于「空间换时间」。
 | 
			
		||||
@ -294,3 +310,20 @@ comments: true
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    ```
 | 
			
		||||
 | 
			
		||||
=== "Swift"
 | 
			
		||||
 | 
			
		||||
    ```swift title="leetcode_two_sum.swift"
 | 
			
		||||
    func twoSumHashTable(nums: [Int], target: Int) -> [Int] {
 | 
			
		||||
        // 辅助哈希表,空间复杂度 O(n)
 | 
			
		||||
        var dic: [Int: Int] = [:]
 | 
			
		||||
        // 单层循环,时间复杂度 O(n)
 | 
			
		||||
        for i in nums.indices {
 | 
			
		||||
            if let j = dic[target - nums[i]] {
 | 
			
		||||
                return [j, i]
 | 
			
		||||
            }
 | 
			
		||||
            dic[nums[i]] = i
 | 
			
		||||
        }
 | 
			
		||||
        return [0]
 | 
			
		||||
    }
 | 
			
		||||
    ```
 | 
			
		||||
 | 
			
		||||
@ -120,7 +120,7 @@ comments: true
 | 
			
		||||
 | 
			
		||||
- 「根结点 Root Node」:二叉树最顶层的结点,其没有父结点;
 | 
			
		||||
- 「叶结点 Leaf Node」:没有子结点的结点,其两个指针都指向 $\text{null}$ ;
 | 
			
		||||
- 结点所处「层 Level」:从顶置底依次增加,根结点所处层为 1 ;
 | 
			
		||||
- 结点所处「层 Level」:从顶至底依次增加,根结点所处层为 1 ;
 | 
			
		||||
- 结点「度 Degree」:结点的子结点数量。二叉树中,度的范围是 0, 1, 2 ;
 | 
			
		||||
- 「边 Edge」:连接两个结点的边,即结点指针;
 | 
			
		||||
- 二叉树「高度」:二叉树中根结点到最远叶结点走过边的数量;
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user