LeetCode解题报告—— Search in Rotated Sorted Array & Search for a Range & Valid Sudoku
1. Search in Rotated Sorted Array
Suppose an array sorted in ascending order is rotated(轮流,循环) at some pivot(枢轴; 中心点) unknown to you beforehand(提前; 事先).
(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).
You are given a target value to search. If found in the array return its index, otherwise return -1.
You may assume no duplicate exists in the array.
解析:这题要求是在一个数组中搜索目标数字,数组是经过升序排序后再按某一点旋转得来的,比如从 0 1 2 4 5 6 7 到 4 5 6 7 0 1 2。这个数组的特点是旋转轴的左边任何一个数字都比旋转轴右边数组中的数字要大,抓住这个特点利用改进的二分查找来解题。
public class Solution {
public int search(int[] A, int target) {
int lo = 0;
int hi = A.length - 1;
while (lo < hi) {
int mid = (lo + hi) / 2;
if (A[mid] == target) return mid;
// 这里判断数组 lo~mid 是不是旋转轴左边的一个升序部分,如果不是那么 mid~hi 构成右边的一个升序部分
if (A[lo] <= A[mid]) {
// 如果target在这个左边升序部分那么在这个升序部分内继续二分查找,否则将lo置为mid后一位继续查找
if (target >= A[lo] && target < A[mid]) {
hi = mid - 1;
} else {
lo = mid + 1;
}
} else {
if (target > A[mid] && target <= A[hi]) {
lo = mid + 1;
} else {
hi = mid - 1;
}
}
}
return A[lo] == target ? lo : -1;
}
}
这题之所以要使用修改的二分查找是因为原数组再旋转后不是一个有序的数组了,就算 nums[mid]<target 也不能确定target再mid的左边还是右边,还要额外判断才行。
2. Search for a Range
Given an array of integers sorted in ascending order, find the starting and ending position of a given target value.
Your algorithm's runtime complexity must be in the order of O(log n).
If the target is not found in the array, return [-1, -1].
For example,
Given [5, 7, 7, 8, 8, 10] and target value 8,
return [3, 4].
解析:在一个升序数组中找一个数字出现的第一位置和最后一个位置,如果找不到则返回-1,难点在于如何再O(log n)内完成。使用线性扫描分别从左,右扫描找到第一个和最后一个,但是这样时间复杂度是O(n)。可以使用改进的二分查找来解决此题,当nums[mid]>=target时,target最左边的位置一定是在mid之前,或者是在mid上,而target最右边的位置一定出现再mid之后或者再mid上,所以将mid置为hi;如果nums[mid]<target,则表明target的最初出现位置在mid之后,继续二分查找。当lo>=hi时查找结束,此时如果 nums[mid]=target 则找到了最左(右)位置,否则返回-1。
下面的这个算法是首先利用二分查找找出第一个大于等于target的索引 start,如果start为数组长度length或者start位置的值不等于(也就是大于)target的话,则返回[-1, -1]。如果是等于则找到了第一个target出现的位置,再按次方法找target+1出现的第一个位置的索引,再减1即找到了最后一个target出现的位置。(注意此时target是确定存在的,所以 target+1 出现的位置一定是最后一个target出现的位置,当然有可能和第一个target的位置重合,即数组中target只出现了一次)
import java.util.*;
public class LeetCode{
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
String input=sc.nextLine().replaceAll("\\]|\\[| ",""); // 替换所有指定字符使用的是replaceAll方法,不是replace,谨记
int target=sc.nextInt();
String[] strs=input.split(",");
int[] A=new int[strs.length];
for(int i=0;i<strs.length;i++)
A[i]=Integer.parseInt(strs[i]);
int[] res=new int[2];
int start=firstGreaterEqual(A, target);
if(start==A.length||A[start]!=target) // firstGreaterEqual方法第一次调用就可以判断出数组中存不存在target
res = new int[]{-1,-1};
else
res = new int[]{start, firstGreaterEqual(A, target+1)-1};
for(int a:res)
System.out.print(a+" ");
}
static int firstGreaterEqual(int[] A, int target){
int low=0, high=A.length;
while(low<high){
int mid=low+((high-low)>>1);
if(A[mid]<target){
low=mid+1;
}else{
high=mid;
}
}
return low;
}
}
3. Valide Sudoku
Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. The Sudoku board could be partially filled, where empty cells are filled with the character '.'.
图
解析:判断给定的数独是否合法,这题可以遍历二维数组来实现,行和列的判断不难,但是如何判断一个九宫格(3*3)内的数字是否不重复呢?难点在于根据行索引 i,和列索引 j 来对应九宫格内的索引,感觉是一道找规律的数学题额。
用第一行的索引构造第一个九宫格的索引,第二行的索引构造第二个九宫格的索引,以此类推。
public boolean isValidSudoku(char[][] board) {
for(int i = 0; i<9; i++){
HashSet<Character> rows = new HashSet<Character>();
HashSet<Character> columns = new HashSet<Character>();
HashSet<Character> cube = new HashSet<Character>();
for (int j = 0; j < 9;j++){
if(board[i][j]!='.' && !rows.add(board[i][j])) //HashSet的add方法,如果元素不在集合中则添加成功,返回true
return false;
if(board[j][i]!='.' && !columns.add(board[j][i]))
return false;
/* 下面部分根据行索引i和列索引j来构造九宫格内的索引,比如在第一个循环中
* i是0,j是从0到9,由此来构造第一个九宫格内的索引:
* [0,0],[0,1],[0,2]
* [1,0],[1,1],[1,2]
* [2,0],[2,1],[2,2]
*/
int RowIndex = 3*(i/3); //0~2为一组,行基准为0;3~5为一组,行基准为3;6~8为一组,行基准是6.
int ColIndex = 3*(i%3); //第二行的索引对应第二个九宫格的索引,所以可以首先判断出行列基准都是和行号有关的
if(board[RowIndex + j/3][ColIndex + j%3]!='.' && !cube.add(board[RowIndex + j/3][ColIndex + j%3])) //在基准的基础上加相对应的值
return false;
}
}
return true;
}
这题说明了一个道理:就是再遍历矩阵的时候。除运算 / 和取余运算 % 是非常有用的。Discussion里也有网友详细说明了这点: https://leetcode.com/problems/valid-sudoku/discuss/15450
LeetCode解题报告—— Search in Rotated Sorted Array & Search for a Range & Valid Sudoku的更多相关文章
- 49. Search in Rotated Sorted Array && Search in Rotated Sorted Array II
Search in Rotated Sorted Array Suppose a sorted array is rotated at some pivot unknown to you before ...
- Search in Sorted Array,Search in Rotated Sorted Array,Search in Rotated Sorted ArrayII
一:Search in Sorted Array 二分查找,可有重复元素,返回target所在的位置,只需返回其中一个位置,代码中的查找范围为[low,high),左闭右开,否则容易照成死循环. 代码 ...
- [Leetcode] Search in Rotated Sorted Array 系列
Search in Rotated Sorted Array 系列题解 题目来源: Search in Rotated Sorted Array Search in Rotated Sorted Ar ...
- LeetCode: Search in Rotated Sorted Array II 解题报告
Search in Rotated Sorted Array II Follow up for "LeetCode: Search in Rotated Sorted Array 解题报告& ...
- LeetCode: Search in Rotated Sorted Array 解题报告
Search in Rotated Sorted Array Suppose a sorted array is rotated at some pivot unknown to you before ...
- 【LeetCode】81. Search in Rotated Sorted Array II 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址:https://leetcode.com/problems/search-in ...
- [LeetCode] Search in Rotated Sorted Array I (33) && II (81) 解题思路
33. Search in Rotated Sorted Array Suppose a sorted array is rotated at some pivot unknown to you be ...
- leetCode 33.Search in Rotated Sorted Array(排序旋转数组的查找) 解题思路和方法
Search in Rotated Sorted Array Suppose a sorted array is rotated at some pivot unknown to you before ...
- leetCode 81.Search in Rotated Sorted Array II (旋转数组的搜索II) 解题思路和方法
Follow up for "Search in Rotated Sorted Array": What if duplicates are allowed? Would this ...
随机推荐
- HDOJ(HDU).2546 饭卡(DP 01背包)
HDOJ(HDU).2546 饭卡(DP 01背包) 题意分析 首先要对钱数小于5的时候特别处理,直接输出0.若钱数大于5,所有菜按价格排序,背包容量为钱数-5,对除去价格最贵的所有菜做01背包.因为 ...
- [mysql]tpcc相关及画图
参考:http://blog.chinaunix.net/uid-26896862-id-3563600.html 参考:http://blog.chinaunix.net/uid-25266990- ...
- bzoj4810 [Ynoi2017]由乃的玉米田 bitset优化+暴力+莫队
[Ynoi2017]由乃的玉米田 Time Limit: 30 Sec Memory Limit: 256 MBSubmit: 917 Solved: 447[Submit][Status][Di ...
- HDU3666 差分约束
THE MATRIX PROBLEM Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Other ...
- 【PHP】Windows下配置用mail()发送邮件
ZZ:解决windows系统下php.ini邮件配置正确不发送邮件的问题 php mail()函数在windows不能用,需要安装sendmail,假如是用的XAMPP,则已经下载好,不需要重新下载~ ...
- Sandglass
题目描述 We have a sandglass consisting of two bulbs, bulb A and bulb B. These bulbs contain some amount ...
- 8.IO模型
一.事件驱动模型 服务器处理模型程序,通常有以下几种: (1)收到一个请求则创建一个新的进程来处理这个请求 (2)收到一个请求则创建一个新的线程来处理这个请求 (3)收到一个请求,把它放入事件列表,让 ...
- 知问前端——Ajax提交表单
本文,运用两大表单插件,完成数据表新增的工作. 一.创建数据库 创建一个数据库,名称为:zhiwen,表——user表,字段依次为:id.name.pass.email.sex.birthday.da ...
- Java中哈希表(Hashtable)是如何实现的
Java中哈希表(Hashtable)是如何实现的 Hashtable中有一个内部类Entry,用来保存单元数据,我们用来构建哈希表的每一个数据是Entry的一个实例.假设我们保存下面一组数据,第一列 ...
- 【BZOJ】1096 [ZJOI2007]仓库建设
[算法]DP+斜率优化 [题解]状态转移方程:f[i]=min(f[j]+g(i+1,j-1))+c[i] 关键在于如何O(1)计算g(i+1,j-1). 推导过程:http://blog.csdn. ...