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的更多相关文章

  1. 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 ...

  2. Search in Sorted Array,Search in Rotated Sorted Array,Search in Rotated Sorted ArrayII

    一:Search in Sorted Array 二分查找,可有重复元素,返回target所在的位置,只需返回其中一个位置,代码中的查找范围为[low,high),左闭右开,否则容易照成死循环. 代码 ...

  3. [Leetcode] Search in Rotated Sorted Array 系列

    Search in Rotated Sorted Array 系列题解 题目来源: Search in Rotated Sorted Array Search in Rotated Sorted Ar ...

  4. LeetCode: Search in Rotated Sorted Array II 解题报告

    Search in Rotated Sorted Array II Follow up for "LeetCode: Search in Rotated Sorted Array 解题报告& ...

  5. LeetCode: Search in Rotated Sorted Array 解题报告

    Search in Rotated Sorted Array Suppose a sorted array is rotated at some pivot unknown to you before ...

  6. 【LeetCode】81. Search in Rotated Sorted Array II 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址:https://leetcode.com/problems/search-in ...

  7. [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 ...

  8. 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 ...

  9. leetCode 81.Search in Rotated Sorted Array II (旋转数组的搜索II) 解题思路和方法

    Follow up for "Search in Rotated Sorted Array": What if duplicates are allowed? Would this ...

随机推荐

  1. libudev使用说明书

    转http://blog.csdn.net/coroutines/article/details/38067805 1. 初始化 首先调用udev_new,创建一个udev library conte ...

  2. JAVA 枚举单例模式

     1.枚举单例模式的实现 public enum Singleton { INSTANCE { @Override protected void read() { System.out.println ...

  3. async/await 里的并行和串行

    我们在使用 async/await 语法时,有时会这样用: function getName () { return new Promise((resolve, reject)=>{ setTi ...

  4. 怎么修改jar包中的class文件然后再重新打成jar包

    1.导入到eclipse中, 修改完了 然后导出jar即可 2.jar cf file.jar *.class 将当前目录下所有CLASS文件打包成新的JAR文件 3.对于补丁.之前已经有jar 例如 ...

  5. 最大公倍数_Greatest Common Divisor

    计算最大公倍数 Static int gcd( int a, int b) { int t; while( b>0) { t = b; b = a % b; a = t; } return a; ...

  6. Ant打jar包时,参数名被修改的问题

    https://blog.csdn.net/landehuxi/article/details/42678117 使用Ant打jar包后,发现jar包中的方法名会在前面自动添加了“param”前缀,导 ...

  7. 洛谷P3764 签到题 III

    题目背景 pj组选手zzq近日学会了求最大公约数的辗转相除法. 题目描述 类比辗转相除法,zzq定义了一个奇怪的函数: typedef long long ll; ll f(ll a,ll b) { ...

  8. bASE--Risk

    //参考base-4.0.2.jar public class Risk implements Serializable //规则名public String ruleName; //规则包名publ ...

  9. Java——关于static关键字的那些事总结

    前言: 先说说今天为啥要谈这个东西,虽然学Java已经有两年了,但是今天,本着温故而知新的态度,仔细的第三次翻看了<Head Firt Java>这本书,虽然这本书介绍的很多东西都特别基础 ...

  10. H264协议(转)

    码率(Bitrate).帧率(FPS).分辨率和清晰度的联系与区别:https://blog.csdn.net/pc9319/article/details/79621352 H.264编码原理以及I ...