难度:简单
题目要求:
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
示例1:
输入:nums = [1,3,5,6], target = 5
输出:2
示例2:
输入:nums = [1,3,5,6], target = 2
输出:1
示例3:
输入:nums = [1,3,5,6], target = 7
输出:4
题解:
由题所要求的必须使用时间复杂度为
O(log n)
的算法,所以要采用二分查找
用low
和high
分别表示二分查找的下标范围的上界和下界,初始时low
和high
分别为数组的最小下标和最大下标。每次查找时,取mid
为low
和high
的平均数,判断下标mid
处的数和目标值的大小关系,调整查找的下标范围
查找目标值
target
的时,执行如下操作:
- 如果 n u m s [ m i d ] > t a r g e t nums[mid]>target nums[mid]>target,则如果目标值存在,其位置小于等于
mid
,因此在下标范围 [ l o w , m i d − 1 ] [low,mid-1] [low,mid−1]中继续查找- 如果 n u m s [ m i d ] < t a r g e t nums[mid]
nums[mid]<target ,则如果目标值存在,其位置大于mid
,因此在下标范围 [ m i d + 1 , h i g h ] [mid+1,high] [mid+1,high]中继续查找- 如果 n u m s [ m i d ] = = t a r g e t nums[mid]==target nums[mid]==target,直接返回
mid
- 当 l o w = h i g h low=high low=high时,查找结束,查找结束之后,如果数组中存在目标值,返回
mid
,否则数组中不存在目标值,返回mid + 1
想法代码:
public static int SearchInsert(int[] nums, int target)
{
int low = 0, high = nums.Length - 1;
int mid = 0;
while (low <= high)
{
mid = (high - low) / 2 + low;
if (nums[mid] == target)
{
return mid;
}
else if (nums[mid] < target)
{
low = mid + 1;
}
else
{
high = mid - 1;
}
}
if (target > nums[mid])
{
return mid + 1;
}
else
{
return mid;
}
}
难度:中等
题目要求:
判断一个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
题解:
可以直接使用二位数组来进行一次遍历
创建二维数组 r o w row row和 c o l col col分别记录数独的每一行和每一列中的数字的出现次数,创建三维数组 s u b b o x subbox subbox记录数度中每一个小宫格的数字的出现次数,其中 r o w [ i ] [ i n d e x ] , c o l [ j ] [ i n d e x ] , s u b b o x [ [ i 3 ] , [ j 3 ] , i n d e x ] row[i][index],col[j][index],subbox[[\dfrac{i}{3}],[\dfrac{j}{3}],index] row[i][index],col[j][index],subbox[[3i],[3j],index]分别表示数独的第 i i i行第 j j j列的单元格所在的行、列和小九宫格中,数字 i n d e x + 1 index + 1 index+1出现的次数,其中 0 ≤ i n d e x < 9 0\leq index<9 0≤index<9,对应的数字 i n d e x + 1 index+1 index+1满足 1 ≤ i n d e x + 1 ≤ 9 1\leq index+1 \leq 9 1≤index+1≤9
如果 b o a r d [ i ] [ j ] board[i][j] board[i][j]填入了数字 n n n,则将 r o w [ i ] [ n − 1 ] 、 c o l [ j ] [ n − 1 ] row[i][n-1]、col[j][n-1] row[i][n−1]、col[j][n−1]和 s u b b o x [ [ i 3 ] , [ j 3 ] , i n d e x ] subbox[[\dfrac{i}{3}],[\dfrac{j}{3}],index] subbox[[3i],[3j],index]各加一,则不符合有效的数独条件,返回false
如果遍历结束之后没有出现计数大于一的情况,则符合有效的数独的条件,返回true
想法代码:
public static bool IsValidSudoku(char[][] board)
{
int[,] row = new int[9,9];
int[,] col = new int[9,9];
int[,,] subbox = new int[3, 3, 9];
for (int i = 0; i < 9; i++)
{
for (int j = 0; j < 9; j++)
{
char c = board[i][j];
if (c != '.')
{
int index = c - '0' - 1;
row[i, index]++;
col[j, index]++;
subbox[i / 3, j / 3, index]++;
if (row[i, index] > 1 || col[j, index] > 1 || subbox[i / 3, j / 3, index] > 1)
{
return false;
}
}
}
}
return true;
}