初级算法系列:数组

目录

一、删除排序数组中的重复项

二、买卖股票的最佳时机 II

三、旋转数组

四、存在重复元素

五、只出现一次的数字

六、两个数组的交集 II

七、加一

八、移动零

 九、两数之和

 十、有效的数独

十一、旋转图像

小结


LeetCode 初级算法-数组链接:https://leetcode-cn.com/leetbook/read/top-interview-questions-easy/x2i30g/

一、删除排序数组中的重复项

给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。

不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。

示例 1:

输入:nums = [1,1,2]
输出:2, nums = [1,2]
解释:函数应该返回新的长度 2 ,并且原数组 nums 的前两个元素被修改为 1, 2 。不需要考虑数组中超出新长度后面的元素。


示例 2:

输入:nums = [0,0,1,1,1,2,2,3,3,4]
输出:5, nums = [0,1,2,3,4]
解释:函数应该返回新的长度 5 , 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4 。不需要考虑数组中超出新长度后面的元素。

1.C

(1)双指针(通用法)

int removeDuplicates(int* nums, int numsSize){
    int len = 1, left = 0, right = 1;

    //判断数组长度
    if(numsSize == 0)
        return 0;

    //遍历数组
    while(right < numsSize)
    {
        if(nums[left] != nums[right])   //遇到数字不同
        {
            len++;
            //判断之前是否有重复的数字
            if(right == left + 1)   //无重复
            {
                left = right;
            }
            else                    //有重复
            {
                nums[left + 1] = nums[right];
                left++;
            }
        }
        right++;
    }

    return len;
}

(2)快慢指针

int removeDuplicates(int* nums, int numsSize){
    int slow = 1, fast = 1;

    //判断数组长度
    if(numsSize == 0)
        return 0;

    //遍历数组  fast用于遍历整体数组,slow用于记录不重复数字
    while(fast < numsSize)
    {
        if(nums[fast] != nums[fast - 1])
        {
            nums[slow] = nums[fast];
            slow++;
        }
        fast++;
    }

    return slow;
}

2.Python

(1)快慢指针

class Solution:
    def removeDuplicates(self, nums: List[int]) -> int:
        # 判断数组长度
        n = len(nums)
        if not n:
            return 0
        
        # 遍历数组:fast用于遍历数组,slow用于记录不重复数字
        fast = slow = 1
        while fast < n:
            if nums[fast] != nums[fast - 1]:
                nums[slow] = nums[fast]
                slow += 1

            fast += 1

        return slow
            

二、买卖股票的最佳时机 II

给定一个数组 prices ,其中 prices[i] 是一支给定股票第 i 天的价格。

设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。

注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

示例 1:

输入: prices = [7,1,5,3,6,4]
输出: 7
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
     随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6-3 = 3 。


示例 2:

输入: prices = [1,2,3,4,5]
输出: 4
解释: 在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
     注意你不能在第 1 天和第 2 天接连购买股票,之后再将它们卖出。因为这样属于同时参与了多笔交易,你必须在再次购买前出售掉之前的股票。


示例 3:

输入: prices = [7,6,4,3,1]
输出: 0
解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。

1.C

(1)动态规划

int Max(int a, int b)
{
    return (a > b)? a : b;
}

int maxProfit(int* prices, int pricesSize){
    //动态规划:
    //设计状态:x天手中没有股票最大利润 dp[x][0]
    //         x天交易完后手中持有一支股票最大收益dp[x][1]
    //状态转移方程:dp[x][0] = max{dp[x-1][0], dp[x-1][1]+prices[x]}
    //             dp[x][1] = max{dp[x-1][1], dp[x-1][0]-prices[x]}

    if(pricesSize == 0)
        return 0;

    int dp[pricesSize][2], max = 0;
    dp[0][0] = 0;           //第1天手中没有股票最大利润为0
    dp[0][1] = -prices[0];  //第1天手中有1支股票最大利润为-prices[0]
    for(int i = 1; i < pricesSize; i++)
    {   
        dp[i][0] = Max(dp[i-1][0], dp[i-1][1]+prices[i]);
        dp[i][1] = Max(dp[i-1][1], dp[i-1][0]-prices[i]);
    }

    return dp[pricesSize-1][0];
}

(2)贪心算法

int Max(int a, int b)
{
    return (a > b)? a : b;
}

int maxProfit(int* prices, int pricesSize){
    //贪心算法:(局部问题的最优解)
    //将交易跨度定为隔天,当天买,隔天卖。求以1天为长度的最大利润
    int max = 0;
    for(int i = 0; i < pricesSize - 1; i++)
        max += Max(0, prices[i+1] - prices[i]);

    return max;
}

2.Python

(1)动态规划

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        pricesSize = len(prices)
        if not pricesSize:
            return 0

        dp = [[0]*2 for _ in range(pricesSize)]
        dp[0][0] = 0
        dp[0][1] = -prices[0]
        for i in range(1, pricesSize):
            dp[i][0] = max(dp[i-1][0], dp[i-1][1]+prices[i])
            dp[i][1] = max(dp[i-1][1], dp[i-1][0]-prices[i])
        
        return dp[pricesSize - 1][0]

(2)贪心算法

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        pricesSize = len(prices)
        if not pricesSize:
            return 0

        profit = 0
        for i in range(pricesSize-1):
            profit += max(0, prices[i+1] - prices[i])

        return profit

三、旋转数组

 给你一个数组,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。

示例 1:

输入: nums = [1,2,3,4,5,6,7], k = 3
输出: [5,6,7,1,2,3,4]
解释:
向右轮转 1 步: [7,1,2,3,4,5,6]
向右轮转 2 步: [6,7,1,2,3,4,5]
向右轮转 3 步: [5,6,7,1,2,3,4]


示例 2:

输入:nums = [-1,-100,3,99], k = 2
输出:[3,99,-1,-100]
解释: 
向右轮转 1 步: [99,-1,-100,3]
向右轮转 2 步: [3,99,-1,-100]。

1.C

(1)额外数组

//1.使用额外数组
void rotate(int* nums, int numsSize, int k){
    int newNums[numsSize];

    for(int i = 0; i < numsSize; i++)
         newNums[(i+k)%numsSize] = nums[i];

    for(int i = 0; i < numsSize; i++)
         nums[i] = newNums[i];
    
 }

(2)翻转法

void reversal(int *nums, int numsSize)
{
    for(int i = 0; i < (numsSize / 2); i++)
    {
        int temp = nums[i];
        nums[i] = nums[numsSize - 1 - i];
        nums[numsSize - 1 - i] = temp;
    }

}

void rotate(int* nums, int numsSize, int k){
    int rotate_k = k % numsSize;

    reversal(nums, numsSize);
    reversal(nums, rotate_k);
    reversal(nums + rotate_k, numsSize - rotate_k);
}

2.Python

 (1)额外数组(列表)

class Solution:
    def rotate(self, nums: List[int], k: int) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        length = len(nums)
        newNums = [0]*length

        for i in range(length):
            newNums[(i+k)%length] = nums[i]

        nums[:] = newNums 

(2)切片

class Solution:
    def rotate(self, nums: List[int], k: int) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        length = len(nums)
        k = k % length

        nums[:] = nums[length - k:] + nums[:length - k]

四、存在重复元素

给你一个整数数组 nums 。如果任一值在数组中出现 至少两次 ,返回 true ;如果数组中每个元素互不相同,返回 false 。
 

示例 1:

输入:nums = [1,2,3,1]
输出:true


示例 2:

输入:nums = [1,2,3,4]
输出:false


示例 3:

输入:nums = [1,1,1,3,3,4,3,2,4,2]
输出:true

1.C

(1)快慢指针

int cmp(const void *a, const void *b)
{
    return *(int *)a - *(int *)b;
}

bool containsDuplicate(int* nums, int numsSize){
    
    if(numsSize <= 1)
        return false;

    qsort(nums, numsSize, sizeof(int), cmp);

    int slow = 0, fast = 1;
    while(fast < numsSize)
    {
        if(nums[slow] != nums[fast])slow = fast;
        else return true;
        
        fast++;
    }

    return false;
}

(2)哈希表(开源哈希表)

typedef struct hashTable_t{
    int key;
    UT_hash_handle hh;
}hashTable_t;

bool containsDuplicate(int* nums, int numsSize){
    hashTable_t *set = NULL;
    
    for(int i = 0; i < numsSize; i++)
    {   
        hashTable_t *tmp;
        HASH_FIND_INT(set, &nums[i], tmp);
        if(tmp == NULL)
        {
            tmp = (hashTable_t *)malloc(sizeof(hashTable_t));
            if(tmp != NULL)
            {
                tmp->key = nums[i];
                HASH_ADD_INT(set, key, tmp);
            }
        }
        else
            return true;
    }

    return false;
}

2.Python

(1)集合set的使用(一)

class Solution:
    def containsDuplicate(self, nums: List[int]) -> bool:
        numsSet = set()
        for i in nums:
            if i in numsSet:
                return True
            else:
                numsSet.add(i)

        return False

(2)集合set的使用(二)

class Solution:
    def containsDuplicate(self, nums: List[int]) -> bool:
        return len(nums) != len(set(nums))

五、只出现一次的数字

给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。

说明:

你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?

示例 1:

输入: [2,2,1]
输出: 1


示例 2:

输入: [4,1,2,1,2]
输出: 4

1.C

(1)暴力解法

int cmp(const void *a, const void *b)
{
    return *(int *)a - *(int *)b;
}

int singleNumber(int* nums, int numsSize){
    qsort(nums, numsSize, sizeof(int), cmp);

    //排序后,只出现一次的元素必定在奇数位
    int flag = 0;
    for(int i = 0; i < numsSize; i+=2)
    {
        //判断前后是否存在相同元素
        if(i-1>=0)
        {
            if(nums[i-1] != nums[i]) flag |= 1;
            else flag = 0;
        }
        if(i+1 < numsSize)
        {
            if(nums[i+1] != nums[i]) flag |= 1;
            else flag = 0;
        }

        if(flag)
            return nums[i];
    }

    return nums[0];
}

(2)异或解法(利用异或特性)

位异或:相同为0,不同为1;

异或:0异或任意数为任意数(如:0^5 = 5)

           任意数与自身做运算结果为0(5^5 = 0)

           一个数异或偶数个相同数还是等于原值(如:1 ^ 5 ^ 6 ^ 5 ^ 6 = 1;有点类似取反)

int singleNumber(int* nums, int numsSize){
    int res = 0;
    for(int i = 0; i < numsSize; i++)
        res ^= nums[i];

    return res;
}

2.Python

(1)异或解法

class Solution:
    def singleNumber(self, nums: List[int]) -> int:
        return reduce(lambda x, y: x^y, nums)

六、两个数组的交集 II

给你两个整数数组 nums1 和 nums2 ,请你以数组形式返回两数组的交集。返回结果中每个元素出现的次数,应与元素在两个数组中都出现的次数一致(如果出现次数不一致,则考虑取较小值)。可以不考虑输出结果的顺序。

示例 1:

输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2,2]


示例 2:

输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[4,9]

提示:

  • 1 <= nums1.length, nums2.length <= 1000
  • 0 <= nums1[i], nums2[i] <= 1000

1.C

(1)哈希表

int* intersect(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize){
    int resSize = (nums1Size > nums2Size)? nums2Size: nums1Size;
    int *res = (int *)malloc(sizeof(int) * resSize);

    int map1[1001] = {0}, map2[1001] = {0}, len = 0;
    for(int i = 0; i < nums1Size; i++)
        map1[nums1[i]]++;
    for(int i = 0; i < nums2Size; i++)
        map2[nums2[i]]++;

    for(int i = 0; i < 1001; i++)
    {
        int map1_cnt = map1[i];
        int map2_cnt = map2[i];
        if(map1_cnt > 0 && map2_cnt > 0)
        {
            int cnt = (map1_cnt >= map2_cnt)? map2_cnt : map1_cnt;
            for(int j = 0; j < cnt; j++)
                res[len++] = i;
        }

    }
    *returnSize = len;

    return res;
}

(2)排序+双指针

int cmp(const void *a, const void *b)
{
    return *(int *)a - *(int *)b;
}

int* intersect(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize){
    int resSize = (nums1Size > nums2Size)? nums2Size : nums1Size;
    int *res = (int *)malloc(sizeof(int) * resSize);

    qsort(nums1, nums1Size, sizeof(int), cmp);
    qsort(nums2, nums2Size, sizeof(int), cmp);

    int index1 = 0, index2 = 0, len = 0;
    while(index1 < nums1Size && index2 < nums2Size)
    {
        if(nums1[index1] < nums2[index2])
            index1++;
        else if(nums1[index1] > nums2[index2])
            index2++;
        else
        {
            res[len++] = nums1[index1];
            index1++;
            index2++;
        }
    }
    *returnSize = len;

    return res;
}

(3)暴力解法

//1.从短的数组 进行检索,所以只需要一个指针
int cmp(const void *a, const void *b)
{
    return *(int *)a - *(int *)b;
}

int* intersect(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize){

    int longSize = (nums1Size > nums2Size)? nums1Size : nums2Size;
    int shortSize = (nums1Size > nums2Size)? nums2Size : nums1Size;
    int *res = (int *)malloc(sizeof(int) * shortSize);

    qsort(nums1, nums1Size, sizeof(int), cmp);
    qsort(nums2, nums2Size, sizeof(int), cmp);

    int index = 0, len = 0;
    for(int i = 0; i < shortSize; i++)
    {
        for(int j = index; j < longSize; j++)
        {

            if((nums1Size >= nums2Size) && (nums1[j] == nums2[i]))
            {
                res[len++] = nums1[j];
                index = j+1;
                break;
            }
            else if((nums1Size < nums2Size) && (nums1[i] == nums2[j]))
            {
                res[len++] = nums2[j];
                index = j+1;
                break;
            }
        }
    }
    *returnSize = len;

    return res;
}

2.Python

(1)排序+双指针

class Solution:
    def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]:
        nums1.sort()
        nums2.sort()

        res = list()
        len1, len2 = len(nums1), len(nums2)
        index1 = index2 = 0
        while index1 < len1 and index2 < len2:
            if nums1[index1] < nums2[index2]:
                index1 += 1
            elif nums1[index1] > nums2[index2]:
                index2 += 1
            else:
                res.append(nums1[index1])
                index1 += 1
                index2 += 1

        return res

(2)哈希表(字典)

class Solution:
    def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]:
        if len(nums1) < len(nums2):
            return self.intersect(nums2, nums1)

        c = collections.Counter(nums2)

        res = list()
        for i in nums1:
            if i in c and c[i] > 0:
                res.append(i)
                c[i] -= 1

        return res

七、加一

给定一个由 整数 组成的 非空 数组所表示的非负整数,在该数的基础上加一。

最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。

你可以假设除了整数 0 之外,这个整数不会以零开头。

示例 1:

输入:digits = [1,2,3]
输出:[1,2,4]
解释:输入数组表示数字 123。


示例 2:

输入:digits = [4,3,2,1]
输出:[4,3,2,2]
解释:输入数组表示数字 4321。


示例 3:

输入:digits = [0]
输出:[1]
 

提示:

1 <= digits.length <= 100
0 <= digits[i] <= 9

1.C

(1)数学规律

数学规律:逢9变0(找到最长后缀9)

int* plusOne(int* digits, int digitsSize, int* returnSize){
    for(int i = digitsSize - 1; i >= 0; i--)
    {
        if(digits[i] == 9) 
            digits[i] = 0;
        else
        {
            digits[i]++;
            *returnSize = digitsSize;
            return digits;
        }
    }

    *returnSize = digitsSize + 1;
    int *res = (int *)malloc(sizeof(int) * (digitsSize +1));
    memset(res, 0, sizeof(int) * (digitsSize + 1));
    res[0] = 1;

    return res;
}

2.Python

(1)暴力解法(字符串与整型的转换)

class Solution:
    def plusOne(self, digits: List[int]) -> List[int]:
        newInt = int(''.join([str(i) for i in digits])) + 1
        newList = [int(i) for i in str(newInt)]
        return newList


# 整理成一行
class Solution:
    def plusOne(self, digits: List[int]) -> List[int]:
        return [int(i) for i in str(int(''.join([str(i) for i in digits])) + 1)]

八、移动零

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

示例:

输入: [0,1,0,3,12]
输出: [1,3,12,0,0]
说明:

必须在原数组上操作,不能拷贝额外的数组。
尽量减少操作次数。

1.C

(1)快慢指针

void moveZeroes(int* nums, int numsSize){
    int slow = 0, fast = 0;

    while(fast < numsSize)
    {
        if(nums[fast] != 0)
        {
            nums[slow] = nums[fast];
            slow++;
        } 

        fast++;
    }

    for(int i = slow; i < numsSize; i++)
        nums[i] = 0;
}

2.Python

(1)列表的删除与添加

class Solution:
    def moveZeroes(self, nums: List[int]) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        cnt = 0
        while 0 in nums:
            nums.remove(0)
            cnt += 1
        
        for i in range(cnt):
            nums.append(0)

 九、两数之和

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target  的那 两个 整数,并返回它们的数组下标。

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。

你可以按任意顺序返回答案。

示例 1:

输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。


示例 2:

输入:nums = [3,2,4], target = 6
输出:[1,2]


示例 3:

输入:nums = [3,3], target = 6
输出:[0,1]
 

提示:

2 <= nums.length <= 104
-109 <= nums[i] <= 109
-109 <= target <= 109
只会存在一个有效答案

1.C

(1)暴力解法

int* twoSum(int* nums, int numsSize, int target, int* returnSize){
    *returnSize = 2;
    int *res = (int *)malloc(sizeof(int) * 2);


    for(int i = 0; i < numsSize; i++)
    {
        for(int j = i + 1; j < numsSize; j++)
        {
            if(nums[i] + nums[j] == target)
            {
                res[0] = i;
                res[1] = j;
                return res;
            }
        }
    }

    return res;
}

(2) 哈希表

typedef struct hashTable_t {
    int id;
    int index;
    UT_hash_handle hh;
}hashTable_t;

hashTable_t* hashtable;

hashTable_t* find(int id) {
    hashTable_t* tmp;
    HASH_FIND_INT(hashtable, &id, tmp);
    return tmp;
}

void insert(int id, int index) {
    hashTable_t* it = find(id);
    if (it == NULL) 
    {
        hashTable_t* tmp = malloc(sizeof(hashTable_t));
        tmp->id = id;
        tmp->index = index;
        HASH_ADD_INT(hashtable, id, tmp);
    } else 
    {
        it->id = id;
    }
}

int* twoSum(int* nums, int numsSize, int target, int* returnSize) {
    hashtable = NULL;
    for (int i = 0; i < numsSize; i++)
    {
        hashTable_t* it = find(target - nums[i]);
        if (it != NULL) {
            int* ret = malloc(sizeof(int) * 2);
            ret[0] = it->index;
            ret[1] = i;
            *returnSize = 2;
            return ret;
        }
        insert(nums[i], i);
    }
    *returnSize = 0;
    return NULL;
}

2.Python

(1)暴力解法

class Solution(object):
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        res = list()
        for i in range(len(nums)):
            for j in range(i+1, len(nums)):
                if nums[i] + nums[j] == target:
                    res.append(i)
                    res.append(j)
                    return res

        return res

(2)哈希表(内置字典的使用)

class Solution(object):
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        hashTable = dict()
        for i in range(len(nums)):
            newTarget = target - nums[i]
            if newTarget in hashTable:
                return [hashTable[newTarget], i]
            hashTable[nums[i]] = i

 十、有效的数独

请你判断一个 9 x 9 的数独是否有效。只需要 根据以下规则 ,验证已经填入的数字是否有效即可。

数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)

 

注意:

一个有效的数独(部分已被填充)不一定是可解的。
只需要根据以上规则,验证已经填入的数字是否有效即可。
空白格用 '.' 表示。

 

示例 1:

输入:board = 
[["5","3",".",".","7",".",".",".","."]
,["6",".",".","1","9","5",".",".","."]
,[".","9","8",".",".",".",".","6","."]
,["8",".",".",".","6",".",".",".","3"]
,["4",".",".","8",".","3",".",".","1"]
,["7",".",".",".","2",".",".",".","6"]
,[".","6",".",".",".",".","2","8","."]
,[".",".",".","4","1","9",".",".","5"]
,[".",".",".",".","8",".",".","7","9"]]
输出:true

示例 2:

输入:board = 
[["8","3",".",".","7",".",".",".","."]
,["6",".",".","1","9","5",".",".","."]
,[".","9","8",".",".",".",".","6","."]
,["8",".",".",".","6",".",".",".","3"]
,["4",".",".","8",".","3",".",".","1"]
,["7",".",".",".","2",".",".",".","6"]
,[".","6",".",".",".",".","2","8","."]
,[".",".",".","4","1","9",".",".","5"]
,[".",".",".",".","8",".",".","7","9"]]
输出:false
解释:除了第一行的第一个数字从 5 改为 8 以外,空格内其他数字均与 示例1 相同。 但由于位于左上角的 3x3 宫内有两个 8 存在, 因此这个数独是无效的。

提示:

  • board.length == 9
  • board[i].length == 9
  • board[i][j] 是一位数字(1-9)或者 '.'

1.C

(1)哈希表

bool isValidSudoku(char** board, int boardSize, int* boardColSize){
    //三种哈希表:行、列、宫
    int hash_row[9][10] = {0}, hash_col[9][10] = {0}, hash_Sudoku[9][10] = {0};

    //将board种的.换成0
    for(int row = 0; row < 9; row++)
    {
        for(int col = 0; col < 9; col++)
        {
            if(board[row][col] == '.')
                board[row][col] = '0';
        }
    }

    //填充哈希表
    //行
    for(int row = 0 ; row < 9; row++)
    {
        for(int i = 0; i < 9; i++)
            hash_row[row][board[row][i] - '0']++;
    }

    //列
    for(int col = 0; col < 9; col++)
    {
        for(int i = 0; i < 9; i++)
            hash_col[col][board[i][col] - '0']++;
    }

    //宫格
    for(int i = 0; i < 9; i++)
    {
        int r = i / 3;
        int c = i % 3;
        for(int row = r*3; row < r*3+3; row++)
        {
            for(int col = c*3; col < c*3+3; col++)
                hash_Sudoku[i][board[row][col] - '0']++;
        }
    }

    //判断
    for(int i = 0; i < 9; i++)
    {
        for(int j = 1; j <= 9; j++)
        {
            if(hash_row[i][j] >= 2 || hash_col[i][j] >= 2 || hash_Sudoku[i][j] >= 2)
                return false;
        }
    }

    return true;
}

2.Python

(1)字典(哈希表)

class Solution(object):
    def isValidSudoku(self, board):
        """
        :type board: List[List[str]]
        :rtype: bool
        """
        hash_row, hash_col, hash_sqrt = defaultdict(set), defaultdict(set), defaultdict(set)
        for row in range(9):
            for col in range(9):
                val = board[row][col]
                if val == '.':
                    continue
                point = row // 3 * 3 + col // 3  # 判断在什么宫格
                if val in hash_row[row] or val in hash_col[col] or val in hash_sqrt[point]:
                    return False
                hash_row[row].add(val)
                hash_col[col].add(val)
                hash_sqrt[point].add(val)
        return True
                

十一、旋转图像

给定一个 n × n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。

你必须在 原地 旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。

示例 1:

输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[[7,4,1],[8,5,2],[9,6,3]]

示例 2:

输入:matrix = [[5,1,9,11],[2,4,8,10],[13,3,6,7],[15,14,12,16]]
输出:[[15,13,2,5],[14,3,4,1],[12,6,8,9],[16,7,10,11]]

提示:

  • n == matrix.length == matrix[i].length
  • 1 <= n <= 20
  • -1000 <= matrix[i][j] <= 1000

1.C

(1)找规律

//1.使用额外数组
void rotate(int** matrix, int matrixSize, int* matrixColSize){
    if (matrixSize == 1)
        return;

    int newMatrix[matrixSize][matrixSize];
    for(int i = 0; i < matrixSize; i++)
    {
        for(int j = 0; j < matrixSize; j++)
            newMatrix[i][j] = matrix[i][j];
    }

    for(int i = 0; i < matrixSize; i++)
    {
        for(int j = 0; j < matrixSize; j++)
            matrix[j][matrixSize - i - 1] = newMatrix[i][j];
    }
    
}

//2.原地旋转
void rotate(int** matrix, int matrixSize, int* matrixColSize) {
    for (int i = 0; i < matrixSize / 2; ++i) {        //需要旋转的点,排除了不需要旋转的中心点
        for (int j = 0; j < (matrixSize + 1) / 2; ++j) {        
            int temp = matrix[i][j];
            matrix[i][j] = matrix[matrixSize - j - 1][i];
            matrix[matrixSize - j - 1][i] = matrix[matrixSize - i - 1][matrixSize - j - 1];
            matrix[matrixSize - i - 1][matrixSize - j - 1] = matrix[j][matrixSize - i - 1];
            matrix[j][matrixSize - i - 1] = temp;
        }
    }
}

2.Python

(1)找规律

# 1.额外列表
class Solution(object):
    def rotate(self, matrix):
        """
        :type matrix: List[List[int]]
        :rtype: None Do not return anything, modify matrix in-place instead.
        """
        n = len(matrix)
        matrix_new = [[0]*n for _ in range(n)]

        for i in range(n):
            for j in range(n):
                matrix_new[j][n - i - 1] = matrix[i][j]
        
        matrix[:] = matrix_new

# 2.原地旋转
class Solution:
    def rotate(self, matrix: List[List[int]]) -> None:
        n = len(matrix)
        for i in range(n // 2):
            for j in range((n + 1) // 2):
                matrix[i][j], matrix[n - j - 1][i], matrix[n - i - 1][n - j - 1], matrix[j][n - i - 1] \
                    = matrix[n - j - 1][i], matrix[n - i - 1][n - j - 1], matrix[j][n - i - 1], matrix[i][j]

小结

涉及数组问题的常见解决方法一般有:双指针(快慢指针)、额外数组(排序)、哈希表。

如果注重时间复杂度则,可以使用 哈希表 额外数组(排序)等方式,以空间换时间的方式,来减小时间复杂度。

如果注重空间复杂度,则可以使用 双指针 的方式,以时间换空间的方式,来减小空间复杂度。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不吃鱼的猫丿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值