LeetCode 36. 有效的数独

有效的数独

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

数字 1-9 在每一行只能出现一次。

数字 1-9 在每一列只能出现一次。

数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。

一次遍历法

有效数独的三个条件:

1.同一个数字在每一行只能出现一次;

2.同一个数字在每一列只能出现一次;

3.同一个数字在每一个小九宫格只能出现一次。

去重类问题,我们想到了哈希表的使用,如何结合起来呢?

我们首先考虑行数据,每行有个哈希表,记录了该行中数字出现的频率,数据可组织为:rows = [[key:val]],

由于数独中的数字范围是1到9,因此可以使用数组代替哈希表进行计数,数据可组织为:rows = [[Int]],减少复杂度。

同理,列数据可得

那么小九宫有何规律呢?

仔细观察发现,9x9 分块后变成了3x3,那么小九宫格的索引自然就是 i/3, j/3,此处记录数据的数组容量仍然为9

数据用三维数组形式表示为:subboxes = [[[Int]]]

复杂度分析

时间复杂度:O(1),注意,由于遍历了9x9 = 81次,常量级别的,因此时间复杂度为O(1)

空间复杂度:O(1),占用了常量空间用来记录变量

Swift

swift 复制代码
func isValidSudoku(_ board: [[Character]]) -> Bool {
    
        var rows:[[Int]] = Array(repeating: Array(repeating: 0, count: 9), count: 9)
        var columns = Array(repeating: Array(repeating: 0, count: 9), count: 9)
        var subboxes = Array(repeating: Array(repeating: Array(repeating: 0, count: 9), count: 3), count: 3)
        
        for i in 0..<9 {
            for j in 0..<9 {
                let c = board[i][j]
                
                if c != "." {
                    let index:Int = c.wholeNumberValue! - 1
                    
                    rows[i][index] += 1
                    columns[j][index] += 1
                    subboxes[i/3][j/3][index] += 1;
                    
                    if rows[i][index] > 1 || columns[j][index] > 1 || subboxes[i/3][j/3][index] > 1 {
                        return false
                    }
                }
            }
        }
        
        return true
    }

OC

c 复制代码
- (BOOL)isValidSudoku:(NSArray *)board {
    NSMutableArray *rows = [NSMutableArray arrayWithCapacity:9];
    for (NSInteger i=0; i<9; i++) {
        
        NSMutableArray *itemArr = [NSMutableArray array];
        for (NSInteger j=0; j<9; j++) {
            [itemArr addObject:@(0)];
        }
        [rows addObject:itemArr];
    }
    
    NSMutableArray *columns = [NSMutableArray arrayWithCapacity:9];
    for (NSInteger i=0; i<9; i++) {
        NSMutableArray *itemArr = [NSMutableArray array];
        for (NSInteger j=0; j<9; j++) {
            [itemArr addObject:@(0)];
        }
        [columns addObject:itemArr];
    }
    
    NSMutableArray *subbox = [NSMutableArray arrayWithCapacity:3];
    for (NSInteger i=0; i<3; i++) {
        NSMutableArray *itemArr = [NSMutableArray array];
        for (NSInteger j=0; j<3; j++) {
            NSMutableArray *subItemArr = [NSMutableArray array];
            for (NSInteger k=0; k<9; k++) {
                [subItemArr addObject:@(0)];
            }
            [itemArr addObject:subItemArr];
        }
        [subbox addObject:itemArr];
    }
    
    for (NSInteger i=0; i<9; i++) {
        for (NSInteger j=0; j<9; j++) {
            NSString *c = board[i][j];
            
            if (![c isEqualToString:@"."]) {
                NSInteger idx = [c integerValue];
                
                rows[i][idx] = @([rows[i][idx] integerValue] + 1);
                columns[j][idx] = @([columns[j][idx] integerValue] + 1);
                subbox[i/3][j/3][idx] = @([subbox[i/3][j/3][idx] integerValue] + 1);
                
                if ([rows[i][idx] integerValue] > 1 || [columns[j][idx] integerValue] > 1 ||
                    [subbox[i/3][j/3][idx] integerValue] > 1) {
                    return NO;
                }
            }
        }
    }
    
    return YES;
}

OC 代码又臭又长,大家有没有好的优化建议呢?

相关推荐
重生之我在VS写bug5 分钟前
【C++知识总结2】C++里面的小配角cout和cin
数据结构·c++·算法
HUT_Tyne2658 分钟前
力扣--LCR 141.训练计划III
算法·leetcode·职场和发展
测试杂货铺1 小时前
Postman设置接口关联,实现参数化
自动化测试·软件测试·测试工具·职场和发展·测试用例·接口测试·postman
pzn25061 小时前
蓝桥杯练习题
c++·算法·蓝桥杯
Octopus20771 小时前
【Linux】vim的使用
linux·笔记·学习·vim
奶茶戒断高手2 小时前
【CSP CCF记录】201903-2第16次认证 二十四点
数据结构·c++·算法
xxxmmc2 小时前
Leetcode 290 word Pattern
算法·leetcode·hashmap双映射
羽墨灵丘2 小时前
0-1背包问题(1):贪心算法
算法·贪心算法
vampire-wpre4 小时前
我要成为算法高手-递归篇
算法·深度优先
醒了就刷牙5 小时前
Leetcode 面试150题 88.合并两个有序数组 简单
算法·leetcode·面试