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 代码又臭又长,大家有没有好的优化建议呢?

相关推荐
_OP_CHEN4 分钟前
算法基础篇:(七)基础算法之二分算法 —— 从 “猜数字” 到 “解难题” 的高效思维
c++·算法·蓝桥杯·二分查找·acm·二分答案·二分算法
IT19956 分钟前
Wireshark笔记-DNS流程与数据包解析
笔记·测试工具·wireshark
一匹电信狗8 分钟前
【C++11】Lambda表达式+新的类功能
服务器·c++·算法·leetcode·小程序·stl·visual studio
在等晚安么11 分钟前
力扣面试150题打卡
算法·leetcode·面试
♛小小小让让20 分钟前
python logging模块:专业日志记录
笔记·python
AI科技星35 分钟前
宇宙膨胀速度的光速极限:基于张祥前统一场论的第一性原理推导与观测验证
数据结构·人工智能·经验分享·python·算法·计算机视觉
EXtreme3541 分钟前
C语言指针深度剖析(2):从“数组名陷阱”到“二级指针操控”的进阶指南
c语言·开发语言·算法
luoganttcc1 小时前
介绍一下 机器人坐标转换的 RT 矩阵
算法
搞机械的假程序猿1 小时前
普中51单片机学习笔记-按键
笔记·学习·51单片机
CodeLongBear1 小时前
MySQL进阶学习笔记:从单表查询到多表关联的深度解析(万字详解)
笔记·学习·mysql