classSolution{publicint[]maxSlidingWindow(int[] nums,int k){if(nums.length <1|| k ==0)returnnewint[0];int[] res =newint[nums.length - k +1];int len = nums.length;int maxIndex =-1;//当前滑动窗口中最大值的索引int max = Integer.MIN_VALUE;//当前滑动窗口中的最大值for(int i =0; i < len - k +1; i++){//i表示窗口的左边界if(maxIndex < i){//如果当前最大值不在窗口中
max = nums[i];//此时max已不在窗口中,故先令max等于窗口的左边界,再去与窗口的其他元素进行比较
maxIndex = i;for(int j = i; j < i + k; j++){//遍历长度为k的窗口,找到其中的最大值if(nums[j]> max){
max = nums[j];
maxIndex = j;}}}else{//如果当前最大值还在窗口中if(nums[i + k -1]> max){//只需判断当前新加进的窗口末尾值与之前窗口的最大值的大小
max = nums[i + k -1];
maxIndex = i + k -1;}}
res[i]= max;}return res;//方法二:双端队列(构建单调队列)//队首为最大元素if(nums.length <1|| k ==0)returnnewint[0];
Deque<Integer> deque =newLinkedList<>();int[] res =newint[nums.length - k +1];for(int j =0, i =1- k; j < nums.length; j++, i++){//j表示窗口右边界,i表示窗口左边界if(i >0&& deque.peekFirst()== nums[i -1]){//如果队首就是要移出去的那个元素(左边界的左边一个元素)
deque.removeFirst();//将队首元素移除}while(!deque.isEmpty()&& deque.peekLast()< nums[j]){//如果队尾元素小于要加进的窗口右边界,则将队尾元素移除,不断循环,直到队列为空或者右边界小于队列中的元素。//这是为了保证队列为非严格递减队列,队首元素始终为最大元素
deque.removeLast();}
deque.addLast(nums[j]);if(i >=0){
res[i]= deque.peekFirst();//最大值即为队首元素}}return res;}}
剑指Offer 65.不用加减乘除做加法
分析
Q : 若数字 a 和 b 中有负数,则变成了减法,如何处理?
A : 在计算机系统中,数值一律用 补码 来表示和存储。补码的优势: 加法、减法可以统一处理(CPU只有加法器)。因此,以上方法 同时适用于正数和负数的加法 。
classSolution{publicintadd(int a,int b){while(b !=0){//当进位为0int temp =(a & b)<<1;//计算a与b运算的进位
a = a ^ b;//计算无进位和
b = temp;//把进位赋给b,进入下一轮循环}}}