一、JZ53 数字在升序数组中出现的次数(简单)
1、暴力法,直接遍历记录出现的次数
public class Solution {
public int GetNumberOfK(int [] array , int k) {
int n = 0;
for(int item: array) {
if(item == k) n=n+1;
}
return n;
}
}
2、使用二分法找到对应的左右位置
public class Solution {
//二分查找
private int bisearch(int[] data, double k){
int left = 0;
int right = data.length - 1;
//二分左右界
while(left <= right){
int mid = (left + right) / 2;
if(data[mid] < k)
left = mid + 1;
else if(data[mid] > k)
right = mid - 1;
}
return left;
}
public int GetNumberOfK(int [] array , int k) {
//分别查找k+0.5和k-0.5应该出现的位置,中间的部分就全是k
return bisearch(array, k + 0.5) - bisearch(array, k - 0.5);
}
}
二、JZ4 二维数组中的查找(中等)
1、暴力法,直接两次遍历
public class Solution {
public boolean Find(int target, int [][] array) {
for(int i= 0;i < array.length;i++) {
for(int j= 0;j < array[i].length; j++) {
if(array[i][j] == target) return true;
}
}
return false;
}
}
2、先确定在哪一列,再遍历这一列是否有该值
public class Solution {
public boolean Find(int target, int [][] array) {
//优先判断特殊
if(array.length == 0)
return false;
int n = array.length;
if(array[0].length == 0)
return false;
int m = array[0].length;
//从最左下角的元素开始往左或往上
for(int i = n - 1, j = 0; i >= 0 && j < m; ){
//元素较大,往上走
if(array[i][j] > target)
i--;
//元素较小,往右走
else if(array[i][j] < target)
j++;
else
return true;
}
return false;
}
}
三、JZ11 旋转数组的最小数字(简单)
1、二分查找
import java.util.ArrayList;
public class Solution {
public int minNumberInRotateArray(int [] array) {
// 特殊情况判断
if (array.length== 0) {
return 0;
}
// 左右指针i j
int i = 0, j = array.length - 1;
// 循环
while (i < j) {
// 找到数组的中点 m
int m = (i + j) / 2;
// m在左排序数组中,旋转点在 [m+1, j] 中
if (array[m] > array[j]) i = m + 1;
// m 在右排序数组中,旋转点在 [i, m]中
else if (array[m] < array[j]) j = m;
// 缩小范围继续判断
else j--;
}
// 返回旋转点
return array[i];
}
}
四、字符串的排列(中等)
1、回溯+交换
import java.util.ArrayList;
import java.util.HashSet;
public ArrayList<String> Permutation(String str) {
ArrayList<String> result = new ArrayList<String>();
if(str == null || str.length() == 0) return result;
char[] charStr = str.toCharArray();
HashSet<String> resSet = new HashSet<String>();
Permutation(charStr,0,resSet);
result.addAll(resSet);
return result;
}
public void Permutation(char[] chars,int begin,HashSet<String> hashSet){
if(chars==null || chars.length==0 || begin<0 || begin>chars.length-1) { return ; }
if(begin == chars.length-1){
// 使用交换,可以节省原来使用的memo记录数据的空间
hashSet.add(String.valueOf(chars));
}else{
for(int i=begin;i<chars.length;i++){
swap(chars,begin,i);
// 设定下标从上一次的下一个下标开始,可以减少循环次数
Permutation(chars,begin+1,hashSet);
swap(chars,begin,i);
}
}
}
public void swap(char[] chars,int begin,int i){
char temp = chars[begin];
chars[begin] = chars[i];
chars[i] = temp;
}
五、JZ44 数字序列中某一位的数字(简单)
1、step 1:通过对每个区间起点数字的计算,按照上述规律求得该区间的位数,n不断减去它前面区间的位数,定位到属于它的区间。step 2:通过除以位数定位n在哪个数字上,用字符串形式表示。step 3:通过在字符串上位置对几位数取模定位目标数字。
import java.util.*;
public class Solution {
public int findNthDigit (int n) {
//位数,起始数字
int bit = 1, start = 1;
//记录当前区间之前总共有多少位数字
long count = 9l;
//将n定位在某个位数的区间中
while(n > count) {
n -= count;
start *= 10;
bit += 1;
//该区间的总共位数
count = Integer.toUnsignedLong(9*start*bit);
}
//定位n在哪个数字上
String num = String.valueOf((n-1) / bit + start);
//定位n在数字的哪一位上
int r = (n-1)%bit;
return Integer.parseInt(num.substring(r, r+1));
}
}