刷题笔记【4】| 快速刷完67道剑指offer(Java版)

在这里插入图片描述

本文已收录于专栏
《刷题笔记》

文章目录

  • 前言
  • 1、数值的整数次方
    • 题目描述
    • 思路一(直接运算)
    • 思路二(快速幂递归版)
    • 思路三(快速幂非递归版)
  • 2、调整数组顺序使奇数位于偶数前面
    • 题目描述
    • 思路一(暴力)
    • 思路二
  • 3、链表中倒数第k个结点
    • 题目描述
    • 思路(快慢指针)
  • 4、反转链表
    • 题目描述
    • 思路(栈)

前言

hi~ ,我是刹那芳间,本专栏题目来源参考阿秀学长的刷题笔记,小戴只是把 C++的题解改成了 Java版本,并整理了其他思路,便于自己的学习~

如果解题有更好的方法,本文也会及时进行更新~

希望对你有帮助~ 一起加油哇~

1、数值的整数次方

牛客原题链接

题目描述

给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方

保证base和exponent不同时为0。不得使用库函数,同时不需要考虑大数问题,也不用考虑小数点后面0的位数

思路一(直接运算)

先处理一些 base 和 exponent 各自为0的情况,

用flag标记 exponent 正负情况,

如果指数为正,直接循环乘就好了,负的话,返回 1/结果

public class Solution {
    public double Power(double base, int exponent) {
        if(exponent==0) return 1.0;
        if(base==0) return 0.0;

        boolean flag = true; // 判断指数是否为正
        if(exponent < 0){
            flag = false;
            exponent = -exponent;
        }
        double res = 1.0;
        for(int i=0; i<exponent; i++){
            res *= base;
        }
        if(flag == true){
            return res;
        }else{
            return 1 / res;
        }
  }
}

思路二(快速幂递归版)

假设求 2的n次方,

当 n为奇数时,2的n次方可以表示为2的二分之n次方乘以
2的二分之n次方再乘以2,

当 n为偶数时,2的n次方可以表示为2的二分之n次方乘以
2的二分之n次方,

我们可以把2的二分之n次方这个中间值用一个变量直接存储

public class Solution {
    public double Power(double base, int exponent) {
        if (exponent == 0) return 1.0;
        if (base == 0) return 0.0;
        if (exponent == 1) return base;

        boolean flag = true;
        if (exponent < 0) {
            flag = false;
            exponent = -exponent;
        }

        double c = Power(base, exponent >> 1); // 用c保存

        double res = 1.0;
        if ((exponent & 1) == 1) { //奇数
            res = c * c * base;
        } else { // 偶数
            res = c * c;
        }

        if (flag) {
            return res;
        } else {
            return 1 / res;
        }

    }
}

思路三(快速幂非递归版)

public class Solution {
    public double Power(double base, int exponent) {
        if(exponent == 0) return 1.0;
        if(base == 0) return 0.0;

        long n = exponent;
        //当n == INT_MIN时,正数时大于INT_MAX的,所以要用一个大于 INT_MAX的类型来保存
        if(exponent < 0){
            n = exponent*(-1.0); //因为n返回结果是一个double型
        }

        double res = 1.0;
        while(n!=0){
            if((n&1) == 1){
                res *= base;
            }
            base *= base;
            n >>= 1;
        }
        return exponent>0 ? res : 1/res;
  }
}

2、调整数组顺序使奇数位于偶数前面

牛客原题链接

题目描述

输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变

思路一(暴力)

借用辅助数组,先遍历目标数组,把奇数存进辅助数组,再遍历目标数组,把偶数存进辅助数组

mport java.util.*;

public class Solution {
    public void reOrderArray(int [] array) {
        int len = array.length;
        int[] n = new int [len];

        int j = 0;
        for (int i = 0; i < len; i++) {
            if ((array[i] % 2) == 1) { // 奇数
                n[j] = array[i];
                j++;
            }
        }

        for (int i = 0; i < len; i++) {
            if ((array[i] % 2) == 0) { // 偶数
                n[j] = array[i];
                j++;
            }
        }

        for(int i = 0; i < len; i++){
            array[i] = n[i];
        }
    }
}

思路二

这个思路类似冒泡,每次判断是否前面是偶数、奇数在后面,前偶后奇就交换

import java.util.*;
public class Solution {
    public void reOrderArray(int [] array) {
        int len = array.length;

        for(int i=0; i<=len/2+1; i++){
            for(int j=len-1; j>i; j--){
                if((array[j]&1)==1 && (array[j-1]&1)==0){ // 前偶后奇就交换
                    int temp = array[j];
                    array[j] = array[j-1];
                    array[j-1] = temp;
                }
            }
        }
        
    }
}

3、链表中倒数第k个结点

牛客原题链接

题目描述

输入一个链表,输出该链表中倒数第k个结点

思路(快慢指针)

刷题笔记【4】| 快速刷完67道剑指offer(Java版)_第1张图片

fast 指针先走k步,之后 slow 和 fast 同时走,直到 fast 到最后一个位置

/*
public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}*/
public class Solution {
    public ListNode FindKthToTail(ListNode head,int k) {
        if(head==null || k==0){
            return null;
        }

        ListNode slow =  head;
        ListNode fast = slow;
        for(int i=0; i<k; i++){
            if(fast==null){
                return null;
            }
            fast = fast.next;
        }
        while(fast!=null){
            slow = slow.next;
            fast = fast.next;
        }
        return slow;
    }
}

4、反转链表

牛客原题链接

题目描述

给定一个单链表的头结点pHead(该头节点是有值的,比如在下图,它的val是1),长度为n,反转该链表后,返回新链表的表头

思路(栈)

像这种,把东西反过来的,直接先思考栈

/*
public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}*/
import java.util.*;
public class Solution {
    public ListNode ReverseList(ListNode head) {
        // 用栈
        Stack<ListNode> stack = new Stack<>();
        while(head != null){
            stack.push(head);
            head = head.next;
        }
        if(stack.isEmpty()){
            return null;
        }
        ListNode node = stack.pop();
        ListNode l = node;
        while(!stack.isEmpty()){
            ListNode temp = stack.pop();
            node.next = temp;
            node = node.next;
        }
        node.next = null;
        return l;

    }
}

你可能感兴趣的:(刷题笔记,java,leetcode,算法)