剑指offer几道值得一看的题
剑指 Offer 57 - II. 和为s的连续正数序列
滑动窗口
输入一个正整数 target
,输出所有和为 target
的连续正整数序列(至少含有两个数)。
序列内的数字由小到大排列,不同序列按照首个数字从小到大排列。
class Solution {
public int[][] findContinuousSequence(int target) {
// (a+b)/2 *(b-a+1)
int[] nums = new int[target];
for(int i=0;i<target;i++) {
nums[i] = i;
}
List<int[]> list = new ArrayList<>();
int j=1;
for(int i=1;i<=target/2+1;i++) {
for(;j<=target/2+1;j++) {
int curSum = (i+j)*(j-i+1)/2;
if(curSum>target) {
break;
} else if(curSum==target) {
list.add(Arrays.copyOfRange(nums,i,j+1));
break;
}
}
}
return list.toArray(new int[list.size()][]);
}
}
剑指 Offer 53 - I. 在排序数组中查找数字 I
class Solution {
public int search(int[] nums, int target) {
return biLargeSearch(nums,target,0,nums.length-1)-
biLargeSearch(nums,target-1,0,nums.length-1);
}
private int biLargeSearch(int[] nums,int target,int left,int right) {
int mid;
while(left<=right) {
mid = (left+right)/2;
if(nums[mid]>target) right = mid-1;
else left = mid+1;
}
return left;
}
}
剑指 Offer 53 - II. 0~n-1中缺失的数字
还是右边界问题。
class Solution {
public int missingNumber(int[] nums) {
int start = 0;
int end = nums.length-1;
int mid;
while(start<=end) {
mid = (start+end)/2;
if(nums[mid]==mid) start=mid+1;
else end=mid-1;
}
return start;
}
}
剑指 Offer 65. 不用加减乘除做加法
class Solution {
public int add(int a, int b) {
while(b!=0) {
int step = (a&b)<<1;
a = a^b;
b = step;
}
return a;
}
}
剑指 Offer 49. 丑数
class Solution {
public int nthUglyNumber(int n) {
int[] ugly = new int[n+1];
ugly[1] = 1;
//比较三个指针
int p2 = 1;
int p3 = 1;
int p5 = 1;
for(int i=2;i<=n;i++) {
int a = ugly[p2]*2;
int b = ugly[p3]*3;
int c = ugly[p5]*5;
if(a<=b&&a<=c) {
ugly[i]=a;
p2++;
}
if(b<=a&&b<=c) {
ugly[i]=b;
p3++;
}
if(c<=a&&c<=b) {
ugly[i]=c;
p5++;
}
}
//System.out.println(Arrays.toString(ugly));
return ugly[n];
}
}
剑指 Offer 59 - I. 滑动窗口的最大值
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
if(nums.length==0) return new int[0];
Deque<Integer> deque = new LinkedList<>();
int[] result = new int[nums.length-k+1];
int resultIndex = 0;
for(int i=0;i<k;i++) {
while(!deque.isEmpty()&&nums[i]>deque.getLast()) deque.pollLast();
deque.addLast(nums[i]);
}
result[resultIndex++] = deque.getFirst();
for(int i=k;i<nums.length;i++) {
//如果滑动窗口移除的元素和队列头相同,说明该元素已经不在窗口内,此时队列头出队
if(deque.getFirst()==nums[i-k]) deque.pollFirst();
while(!deque.isEmpty()&&nums[i]>deque.getLast()) deque.pollLast();
deque.addLast(nums[i]);
result[resultIndex++]=deque.getFirst();
}
return result;
}
}