LeetCode 初级算法 JAVA实现

26.删除数组中重复元素

自己写的是遍历一个数,找到其重复的个数,设置一个指针记录总重复数,也就找到了最后要访问的节点,有重复的则将后面的元素往前挪
设置快慢指针,慢指针不同才走,快指针走完全程时,慢指针刚好走到剩余元素完。
class Solution {
   public int removeDuplicates(int[] nums) {
        if (nums == null||nums.length == 0){
            return 0;
        }
        if (nums.length == 1){
            return 1;
        }
        int count = 0;
        for (int x = 0;x<=nums.length-2-count;x++){
            int y = x;
            int temp_count = 0;
            while (y <= nums.length-2-count && nums[y] == nums[y+1] ){
                temp_count++;
                y++;
            }
            if (temp_count != 0){
                //前移
                for (int z = x+temp_count+1;z<=nums.length-1;z++){
                    nums[z-temp_count] = nums[z];
                }
                count += temp_count;
            }
        }
        return nums.length-count;
    }
}

面试题122:买卖股票的最佳时间2

动态规划,从尾到头求在第n天买的最大价值是多少
题目意思可以当天卖了之后买,故把连续的差值相加即可
public static int maxProfit(int[] prices) {
        if (prices == null || prices.length <= 1){
            return 0;
        }
        int days = prices.length;
        int[] price_day = new int[days];
        price_day[days-1] = 0;
        for (int x = days-2;x>=0;x--){
            int max = 0;
            for (int y = x+1;y<=days-1;y++){
                if (prices[y] > prices[x]){
                    int temp = prices[y] - prices[x];
                    if (y<= days-2){
                        temp += price_day[y+1];
                    }
                    if (temp > max){
                        max = temp;
                    }
                }
            }
            //如果最大值比当天不买还小,取当天不买
            if (maxmaxprice){
                maxprice = x;
            }
        }
        return maxprice;
    }

面试题136:只出现一次的数字(剑指offer)

遍历异或
面试题350:两个数组的交集
用hash表存下一个数组的元素,再进行比对
将两个数组排序,再进行比较
    public int[] intersect(int[] nums1, int[] nums2) {
        int[] reback = {};
        if (nums1 == null || nums2 == null || nums1.length == 0 || nums2.length == 0){
            return reback;
        }
        List temp = new ArrayList<>();
        Arrays.sort(nums1);
        Arrays.sort(nums2);
        int start = 0;
        for (int x : nums2){
            for (int y = start;y<=nums1.length-1;y++){
                if (nums1[y] == x){
                    temp.add(x);
                    start = y+1;
                    break;
                }
            }
        }

        if (temp.size() == 0){
            return reback;
        }
        reback = new int[temp.size()];
        for (int x = 0;x<=reback.length-1;x++){
            reback[x] = temp.get(x);
        }
        return reback;
    }

面试题66:加一

从尾到头计算,考虑进位,可以直接把加一思考为一开始carry=1;
    public static int[] plusOne(int[] digits) {
        if ( digits == null || digits.length == 0){
            return digits;
        }
        int carry = 0;
        digits[digits.length-1] = digits[digits.length-1]+1;
        if (digits[digits.length-1]>=10){
            digits[digits.length-1] = digits[digits.length-1]-10;
            carry = 1;
        }

        for (int x = digits.length-2;x>=0;x--){
            digits[x] = digits[x]+carry;
            if (digits[x] >= 10){
                digits[x] = digits[x]-10;
                carry = 1;
            }else {
                carry = 0;
            }
        }
        if (carry == 1){
            int[] reback = new int[digits.length+1];
            for (int x = 1;x<=reback.length-1;x++){
                reback[x] = digits[x-1];
            }
            reback[0] = 1;
            return reback;
        }
        return digits;
    }

面试题283:移动0

冒泡的思想可解
用快慢指针,快指针找到非0位置后与前一个指针进行交换。
    public static void moveZeroes(int[] nums) {
        if (nums == null||nums.length <= 1){
            return;
        }
        int count = 0;
        for (int x = 0;x<=nums.length-2-count;x++){
            if (nums[x] == 0){
                count++;
                for (int y = x;y<=nums.length-2;y++){
                    exchange(nums,y,y+1);
                }
                if (nums[x] == 0){
                    x--;
                }
            }
        }
    }
    public static void exchange(int[] nums,int index1,int index2){
        nums[index1] = nums[index1]^nums[index2];
        nums[index2]= nums[index1]^nums[index2];
        nums[index1] = nums[index1]^nums[index2];
    }

面试题1:两数之和

若不要求返回下标,可以采用剑指offer上,对数组先排序再从头尾开始扫描的办法。
扫描数组,若hashmap有另一半则返回,若无,则将当前数添加进hashmap
        public int[] twoSum(int[] nums, int target) {
        int[] reback = {};
        if (nums == null || nums.length < 2){
            return reback;
        }
        for (int x = 0;x<=nums.length-2;x++){
            for (int y = x+1;y<=nums.length-1;y++){
                if ((nums[x] + nums[y]) == target){
                    reback = new int[2];
                    reback[0] = x;
                    reback[1] = y;
                    return reback;
                }
            }
        }
        return reback;
    }

面试题36:有效的数独

设置三个hashmap,在一次遍历中,通过数字转化到对应需要检查的位置,来完成一次遍历检查完
    public static boolean isValidSudoku(char[][] board) {
        if (board == null || board.length != 9 || board[0].length != 9){
            return false;
        }
        HashMap hashMap_row = new HashMap<>();
        HashMap hashMap_col = new HashMap<>();
        HashMap hashMap_small = new HashMap<>();
        for (int x = 0;x<=8;x++){
            hashMap_row.clear();
            hashMap_col.clear();
            hashMap_small.clear();
            for (int y = 0;y<=8;y++){
                if (board[x][y] != '.'){
                    if (hashMap_row.containsKey(board[x][y])){
                        return false;
                    }else {
                        hashMap_row.put(board[x][y],true);
                    }
                }
                if (board[y][x] != '.'){
                    if (hashMap_col.containsKey(board[y][x])){
                        return false;
                    }else {
                        hashMap_col.put(board[y][x],true);
                    }
                }
                if (board[x/3*3+y/3][x%3*3+y%3] != '.'){
                    if (hashMap_small.containsKey(board[x/3*3+y/3][x%3*3+y%3])){
                        return false;
                    }else {
                        hashMap_small.put(board[x/3*3+y/3][x%3*3+y%3],true);
                    }
                }
            }
        }
        return true;
    }

面试题48:旋转图像

先沿对角线交换一次元素,再按行的中轴旋转一次,得到旋转后的图像。
public static void rotate(int[][] matrix) {
         if (matrix == null || matrix.length == 0 || matrix[0].length == 0 || matrix.length != matrix[0].length){
             return;
         }
         int row = matrix.length;
         //沿对角线交换
         for (int x = 0;x<=row-2;x++){
             for (int y = row-x-2;y>=0;y--){
                 swamp(matrix,x,y,row-1-y,row-1-x);
             }
         }
         //沿中轴交换
        int middle = (row-1)/2;
         for (int x = 0;x<=middle;x++){
             for (int y = 0;y<=row-1;y++){
                 swamp(matrix,x,y,row-1-x,y);
             }
         }
    }
    public static void swamp(int[][] matrix,int x1,int y1,int x2,int y2){
        int temp = matrix[x1][y1];
        matrix[x1][y1] = matrix[x2][y2];
        matrix[x2][y2] = temp;
    }

面试题344:反转字符串

遍历数组,交换元素的位置。
public static String reverseString(String s) {
        if (s == null||s.length() <= 1){
            return s;
        }
        int needreverse = (s.length()-1)/2;
        char[] S_char = s.toCharArray();
        for (int x = 0;x<=needreverse;x++){
            swap(S_char,x,S_char.length-1-x);
        }
        return String.valueOf(S_char);
    }
    public static void swap(char[] S_char ,int index1,int index2){
        char temp = S_char[index1];
        S_char[index1] = S_char[index2];
        S_char[index2] = temp;
    }

面试题7:颠倒整数

将整数表示为字符串,在字符串中进行操作,并与最大值按位进行比较
可以不用翻转的思想,直接用整数进行预算,(除10,取余,保存)。先将结果用long保存,再进行比较,再输出
char[] num = String.valueOf(x).toCharArray();
        //判断首位正负
        String compare = (int)Math.pow(2,31)+"";
        StringBuilder stringBuilder = new StringBuilder();
        String st = "";
        String st_sub = "";
        if (num[0] == '-'){
            st = swap(num,1,num.length-1);
            st_sub = st.substring(1);
        }else {
            st = swap(num,0,num.length-1);
            st_sub = st;
        }
        //低于10位不存在越界
        if (st_sub.length() == 10){
            for (int i = 0;i<10;i++){
                if (i == 9 && st_sub.charAt(i) >compare.charAt(i)-1 || st_sub.charAt(i)>compare.charAt(i)){
                    return 0;
                }else if (st_sub.charAt(i) < compare.charAt(i)){
                    break;
                }
            }
        }
        if (st == "0"){
            return 0;
        }else {
            stringBuilder.append(st);
        }
        return Integer.parseInt(stringBuilder.toString());

面试题387:字符串中第一个唯一字符

hashmap辅助存储,遍历字符数组,再在hashmap中返回 
字符只在a-z之间,则每次firstindex , lastindex某个字符,若相等则说明只出现一次
    public static int firstUniqChar(String s) {
        if (s == null || s.length() == 0){
            return -1;
        }
        HashMap hashMap = new HashMap<>();
        char[] temp = s.toCharArray();
        for (int x = 0;x<=temp.length-1;x++){
            if (hashMap.containsKey(temp[x])){
                hashMap.replace(temp[x],-1);
            }else {
                hashMap.put(temp[x],x);
            }
        }

        int firstindex = temp.length;
        for (int x:hashMap.values()){
            if (x

面试题242:验证变位词

用hashmap辅助存储
 public static boolean isAnagram(String s, String t) {
        if (s == null || t == null || s.length()!=t.length()){
            return false;
        }
        HashMap hashMap = new HashMap<>();
        for (char x:s.toCharArray()){
            if (hashMap.containsKey(x)){
                hashMap.replace(x,hashMap.get(x)+1);
            }else {
                hashMap.put(x,1);
            }
        }
        for (char x:t.toCharArray()){
            if (hashMap.containsKey(x)){
                hashMap.replace(x,hashMap.get(x)-1);
            }else {
                return false;
            }
        }
        for (int x:hashMap.values()){
            if (x!=0){
                return false;
            }
        }
        return true;
    }

面试题125:验证回文串

用队列辅助比较
设置两个指针一头一尾进行比较
    public static boolean isPalindrome(String s) {
        if (s == null){
            return false;
        }
        if (s.length() <= 1){
            return true;
        }

        ArrayDeque deque = new ArrayDeque() {};
        char[] temp = s.toLowerCase().toCharArray();
        for (char x:temp){
            if ( ( (x<='z' && x>='a') || (x <='9'&& x>='0') )){
                deque.addLast(x);
            }
        }
        for (int x = temp.length-1;x>=0;x--){
            if (( (temp[x]<='z' && temp[x]>='a') || (temp[x] <='9'&& temp[x]>='0') )){
                char compare = deque.pollFirst();
                if (compare != temp[x]){
                    return false;
                }
            }
        }
        return true;
    }

面试题8:字符串转数组

每次检验sum是否会超过边界
    public static int myAtoi(String str) {
        if (str == null || str.length() == 0){
            return 0;
        }
        char[] temp = str.toCharArray();
        int startswords = 0;
        for (int x = 0;x<=temp.length-2;x++){
            if (temp[x] == ' '){
                startswords++;
                if (temp[x+1] != ' '){
                    break;
                }
            }else {
                break;
            }
        }
        if (startswords == temp.length-1 && startswords != 0){
            return 0;
        }
        int num = 0;
        if (temp[startswords] == '+' || temp[startswords] == '-'){
            for (int x = startswords+1;x<=temp.length-1;x++){
                if (temp[x]>'9' || temp[x] <'0'){
                    break;
                }
                if (num >Integer.MAX_VALUE/10 || (num == Integer.MAX_VALUE/10 && (temp[x]-'0') > 7)){
                    return temp[startswords] == '+'?Integer.MAX_VALUE:Integer.MIN_VALUE;
                }
                num = num*10+temp[x]-'0';
            }
            return temp[startswords] == '+'?num:-num;

        }else if (temp[startswords] <= '9' && temp[startswords] >='0'){
            for (int x = startswords;x<=temp.length-1;x++){
                if (temp[x]>'9' || temp[x] <'0'){
                    break;
                }
                if (num >Integer.MAX_VALUE/10 || (num == Integer.MAX_VALUE/10 && (temp[x]-'0') >7)){
                    return Integer.MAX_VALUE;
                }
                num = num*10+temp[x]-'0';
            }
            return num;
        }else {
            return 0;
        }

    }

面试题28:实现strStr()

就是比较母串和子串,遍历到母串-子串长度即可
public static int strStr(String haystack, String needle) {
        if (haystack == null || needle == null || needle.length() == 0){
            return 0;
        }
        if (haystack.length() < needle.length()){
            return -1;
        }
        char[] hay = haystack.toCharArray();
        char[] need = needle.toCharArray();
        for (int x = 0;x<=haystack.length()-1;x++){
            if (hay[x] == need[0]){
                if (x+need.length-1<=haystack.length()-1){
                    int y = 1;
                    for (;y<=need.length-1;y++){
                        if (hay[x+y] != need[y]){
                            break;
                        }
                    }
                    if (y == need.length){
                        return x;
                    }
                }else {
                    return -1;
                }
            }
        }
        return -1;
    }

面试题38:报数

按次数用n-1构造n即可,不可能出现超过3的数
public static String countAndSay(int n) {
        if (n<=0){
            return "";
        }
        StringBuilder stringBuilder = new StringBuilder();
        if (n == 1){
            stringBuilder.append("1");
            return stringBuilder.toString();
        }
        stringBuilder.append("1");
        while (n > 1){
            char[] temp = stringBuilder.toString().toCharArray();
            stringBuilder.delete(0,stringBuilder.length());

            int count = 1;
            if (temp.length == 1){
                stringBuilder.append(1);
                stringBuilder.append(temp[0]);
            }
            for (int x = 0;x<=temp.length-2;x++){
                if (temp[x] == temp[x+1]){
                    count++;
                    if (x == temp.length-2){
                        stringBuilder.append(count);
                        stringBuilder.append(temp[x]);
                        count = 1;
                    }
                }else {
                    stringBuilder.append(count);
                    stringBuilder.append(temp[x]);
                    count = 1;
                }
            }
            if (temp.length>=2 && temp[temp.length-1] != temp[temp.length-2]){
                stringBuilder.append(1);
                stringBuilder.append(temp[temp.length-1]);
            }
            n = n-1;
        }
        return stringBuilder.toString();
    }

面试题14:最长公共子串

遍历数组,两两求出公共子串,不断更新
选取第一个字符串中的字符,每个字符去其余字符串中比较是否有
public static String longestCommonPrefix(String[] strs) {
        if (strs == null || strs.length == 0){
            return "";
        }
        if (strs.length == 1){
            return strs[0];
        }
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(strs[0]);
        for (int x = 1;x<=strs.length-1;x++){
            if (stringBuilder.length() == 0){
                return "";
            }
            String temp = compare(stringBuilder.toString(),strs[x]);
            if (temp.length() < stringBuilder.length()){
                stringBuilder.delete(0,stringBuilder.length());
                stringBuilder.append(temp);
            }
        }
        return stringBuilder.toString();
    }
    public static String compare(String st1,String st2){
        int lenth = st1.length() >= st2.length() ? st2.length():st1.length();
        StringBuilder stringBuilder = new StringBuilder();
        char[] st_char = st1.toCharArray();
        char[] st2_char = st2.toCharArray();
        for (int x = 0;x<=lenth-1;x++){
            if (st_char[x] == st2_char[x]){
                stringBuilder.append(st_char[x]);
            }else {
                break;
            }
        }
        return stringBuilder.toString();
    }

面试题237:删除链表中的节点

用下一节点的值覆盖此节点,并指向下一节点的下一节点。
 public static void deleteNode(ListNode node) {
        if (node == null || node.next == null){
            return;
        }
        node.val = node.next.val;
        node.next = node.next.next;
    }

面试题19:删除链表的倒数N个节点

用栈来进行辅助
用两个指针,一个指针先走N步
 public static ListNode removeNthFromEnd(ListNode head, int n) {
        if (head == null){
            return null;
        }
        ListNode temp = head;
        Stack st = new Stack<>();
        while (temp!=null){
            st.push(temp);
            temp = temp.next;
        }
        ListNode reback = null;
        for (int x = 1;x<=n;x++){
            reback = st.pop();
        }
        if (st.size() == 0){
            return reback.next;
        }else {
            ListNode father = st.pop();
            father.next = reback.next;
            return head;
        }
    }

面试题206:翻转单链表

可以从头到尾遍历,每遍历一个就处理一个;可以设置新的头结点,将原头结点后的接到后面,直到原头结点为尾节点;

递归找到head == null || head.next == null,返回节点,每层保存当前节点;

ublic static ListNode reverseList(ListNode head) {
        if (head == null){
            return null;
        }
        if (head.next == null){
            return head;
        }
        ListNode temp = null;
        while (head!= null){
            ListNode nexttemp = head.next;
            ListNode now = head;
            head.next = temp;
            temp = now;
            head = nexttemp;
            if (head == null){
                return temp;
            }
        }
        return null;
    }
public static ListNode reverseList(ListNode head) {
        if (head == null || head.next == null){
            return head;
        }
        ListNode p = head;
        head = reverseList(p.next);
        p.next.next = p;
        p.next = null;
        return head;

    }

面试题21:合并两个有序链表

新建一个链表,比较两个链表放入较小值,再将未完的放入;
public static ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        if (l1 == null){
            if (l2 == null){
                return null;
            }else {
                return l2;
            }
        }
        if (l2==null){
            return l1;
        }
        ListNode head = new ListNode(-1);
        ListNode cur = head;
        while (l1!=null && l2!=null){
            if (l1.val >= l2.val){
                cur.next = l2;
                cur = cur.next;
                l2 = l2.next;
            }else {
                cur.next = l1;
                cur = cur.next;
                l1 =l1.next;
            }
        }
        while (l1 != null){
            cur.next = l1;
            cur = cur.next;
            l1 = l1.next;
        }
        while (l2 != null){
            cur.next = l2;
            cur = cur.next;
            l2 = l2.next;
        }
        return head.next;
    }

面试题234:回文链表

转化为比较前半与后半的问题,首先用快慢指针定位到链表中间,再将后半链表进行翻转,再比较
public static boolean isPalindrome(ListNode head) {
        if (head == null){
            return true;
        }else if (head.next == null){
            return true;
        }
        ListNode fast = head;
        ListNode slow = head;
        while (fast.next!=null && fast.next.next !=null){
            slow = slow.next;
            fast = fast.next.next;
        }
        ListNode tail = slow.next;
        slow.next = null;
        ListNode newhead = new ListNode(-1);
        newhead.next = tail;
        while (tail.next!=null){
            ListNode temp = tail.next;
            tail.next = tail.next.next;
            temp.next = newhead.next;
            newhead.next = temp;

        }
        newhead = newhead.next;
        while (newhead != null){
            if (newhead.val != head.val){
                return false;
            }
            newhead = newhead.next;
            head = head.next;
        }
        return true;

    }

面试题141:环形链表

快慢指针,如果存在环,最后快指针会追上慢指针

 public static boolean hasCycle(ListNode head) {
        if (head == null || head.next == null){
            return false;
        }
        ListNode fast = head;
        ListNode slow = head;
        while (fast.next != null && fast.next.next != null){
            slow = slow.next;
            fast = fast.next.next;
            if (slow == fast){
                return true;
            }
        }
        return false;
    }

面试题104:二叉树的最大深度

递归
public static int maxDepth(TreeNode root) {
        if (root == null){
            return 0;
        }else if (root.left == null && root.right == null){
            return 1;
        }
        int left = maxDepth(root.left);
        int right = maxDepth(root.right);
        return left>right?left+1:right+1;
    }
面试题98:验证二叉搜索树
构造函数时需要传入应该大于的数和应该小于的数,每个节点不同。
中序遍历为有序序列
public static boolean isValidBST(TreeNode root) {
        if (root == null) return true;
        return valid(root, Long.MIN_VALUE, Long.MAX_VALUE);
    }
    public static boolean valid(TreeNode root, long low, long high) {
        if (root == null) return true;
        if (root.val <= low || root.val >= high) return false;
        return valid(root.left, low, root.val) && valid(root.right, root.val, high);
    }

面试题101:对称二叉树

可以定义一种从右子树开始先序遍历方法,与左遍历相比较
递归比较左右子树对应位置。迭代可以使用两个栈进行辅助
 public static boolean isSymmetric(TreeNode root) {
        if (root == null){
            return true;
        }
        ArrayList arrayList1 = new ArrayList<>();
        ArrayList arrayList2 = new ArrayList<>();
        core_1(root,arrayList1);
        core_2(root,arrayList2);
        System.out.println(arrayList1.toString());
        System.out.println(arrayList2.toString());
        for (int x = 0;x<=arrayList1.size()-1;x++){
            if (arrayList1.get(x)!= arrayList2.get(x)){
                return false;
            }
        }
        return true;
    }
    public static void core_1(TreeNode root,ArrayList arrayList){
        if (root == null){
            arrayList.add(-1);
            return;
        }
        arrayList.add(root.val);
//
        core_1(root.left,arrayList);

        core_1(root.right,arrayList);
    }
    public static void core_2(TreeNode root,ArrayList arrayList){
        if (root == null){
            arrayList.add(-1);
            return;
        }
        arrayList.add(root.val);
        core_2(root.right,arrayList);
        core_2(root.left,arrayList);
    }

面试题102:二叉树的层次遍历(剑指offer写过)

用两个变量维护本层数量,与下层数量

面试题108:将有序数组转化为二叉搜索树

可以用递归构建,每次找到中间的元素作为根
    public static TreeNode sortedArrayToBST(int[] nums) {
        if (nums == null){
            return null;
        }

        TreeNode root = core(nums,0,nums.length-1);
        return root;
    }
    public static TreeNode core(int[] nums,int start,int end){
        if (start>end){
            return null;
        }else if (start == end){
            return new TreeNode(nums[start]);
        }
        int middle = (end-start+1)/2+start;
        TreeNode root = new TreeNode(nums[middle]);
        TreeNode left = core(nums,start,middle-1);
        TreeNode right = core(nums,middle+1,end);
        root.left = left;
        root.right = right;
        return root;
    }

面试题88:合并有序数组

依次将nums2的元素插入nums1
直接比较nums1和nums2比较大的放入nums1的后面
 public static void merge(int[] nums1, int m, int[] nums2, int n) {
        if (nums1 == null || nums2 == null){
            return;
        }
        if (nums1.length < (m+n) || m<0 || n<0){
            return;
        }
        for (int x = m;x<=m+n-1;x++){
            nums1[x] = nums2[x-m];
        }
        int start1 = 0;
        int start2 = m;
        while (start1 < start2){
            if (start2 > m+n-1){
                break;
            }
            if (nums1[start1] > nums1[start2]){
                int temp = nums1[start2];
                start2++;

                for (int x = start2-2;x>=start1;x--){
                    nums1[x+1] = nums1[x];
                }
                nums1[start1] = temp;
                start1++;
            }else {
                start1++;
            }
        }

    }

面试题278:第一个错误的版本

用二分查找边界,当start和end特别大是mid要注意处理
    public int firstBadVersion(int n) {
        if (n<0){
            return -1;
        }
        int start = 1;
        int end = n;
        int mid = 1;

        while (start

面试题70:爬楼梯(剑指offer写过)

f(n) = f(n-1)+f(n+1),用数组将计算过的值存储下来,还可以进一步优化只记录前两个值。

面试题121:买卖股票的最佳时机(剑指offer写过)

维护到当前元素为止出现过的最小值与最大利润
public static int maxProfit(int[] prices) {
        if (prices == null || prices.length <=1){
            return 0;
        }
        int[] lowprice = new int[prices.length];
        lowprice[0] = prices[0];
        for (int x = 1;x<=prices.length-1;x++){
            lowprice[x] = lowprice[x-1] > prices[x-1] ? prices[x-1]:lowprice[x-1];
        }
        int maxprofit = 0;
        for (int x = 0;x<=prices.length-1;x++){
            if (prices[x]-lowprice[x]>maxprofit){
                maxprofit = prices[x]-lowprice[x];
            }
        }
        return maxprofit;
    }

面试题53:最大子序和

动态规划,维护最大值
分治,递归,将数组分为前后两部分,分别求最大值,以及从中间向两边的最大值
 public static int maxSubArray(int[] nums) {
        if (nums == null || nums.length == 0) {
            return 0;
        }else if (nums.length == 1){
            return nums[0];
        }
        int sum = 0;
        int max = nums[0];
        for (int x = 0; x<=nums.length-1;x++){
            sum = sum+nums[x];
            if (sum>max){
                max = sum;
            }
            if (sum < 0){
                sum = 0;
            }
        }
        return max;
    }

面试题198:打家劫舍

f(n) = max{f(n-1), f(n-2)+nums[n]};初始化时,需要初始化0,1位置,f的意思是到n时不相邻数能产生的最大和。
public static int rob(int[] nums) {
        if (nums == null || nums.length == 0){
            return 0;
        }else if (nums.length == 1){
            return nums[0];
        }

        int[] profits = new int[nums.length];
        profits[0] = nums[0];
        profits[1] = nums[1];
        if (nums.length == 2){
            return Math.max(profits[0],profits[1]);
        }
        for (int x = 2;x<=nums.length-1;x++){
            int max = 0;
            for (int y = 0;y<=x-2;y++){
                if (profits[y] > max){
                    max = profits[y];
                }
            }
            profits[x] = Math.max(max+nums[x],profits[x-1]);
        }
        
        return profits[nums.length-1];

    }

面试题384:打乱数组

遍历数组,为当前位置生成一个随机位置(向后),交换
生成一个数组长度的随机数数组,避免重复,再根据下标获取位置。
class Solution {
    private int[] origin;
    public Solution(int[] nums) {
        this.origin = nums.clone();
    }

    /** Resets the array to its original configuration and return it. */
    public int[] reset() {
        return this.origin;
    }

    /** Returns a random shuffling of the array. */
    public int[] shuffle() {
        int lenth = origin.length;
        int[] order = new int[lenth];

        int num;
        int count = 0;
        boolean flag = false;
        while (count

面试题155:最小栈(剑指offer)

再用一个栈维护最小值
面试题412:FizzBuzz
分情况处理即可
 public static List fizzBuzz(int n) {
        List reback = new ArrayList<>();
        if (n<=0){
            return reback;
        }
        for (int x = 1;x<=n;x++){
            if (x%15 == 0){
                reback.add("FizzBuzz");
            }else if (x%3 == 0){
                reback.add("Fizz");
            }else if (x%5 == 0){
                reback.add("Buzz");
            }else {
                reback.add(x+"");
            }
        }
        return reback;
    }

面试题204:计数质数

用标记矩阵,从0-n/2(答案是sqrt(n)),如果当前标记为false,则将其倍数都标记为true,最终再遍历一次数组,得到为false的次数
class Solution {
    public static int countPrimes(int n) {
        if (n<=2){
            return 0;
        }
        boolean[] ifnum = new boolean[n-2];
        int sum = 0;
        int limit = n/2;
        for (int i = 2;i<=limit;i++){
            if (ifnum[i-2] == false){
                for (int j = i*2;j

题目326:3的幂

不能用循环的时候可以用对数函数检查
    public static boolean isPowerOfThree(int n) {
        if (n == 1){
            return true;
        }
        if (n<=2){
            return false;
        }else if (n%2 == 0){
            return false;
        }
        double re = Math.log10(n)/Math.log10(3);
        if ((re-(int)re)==0){
            return true;
        }else {
            return false;
        }

    }

面试题13:罗马数字转整数

规则表示如果当前数小于后一位数则减去当前数,否则加上此位,这种方法只需要遍历字符串一遍
将特殊的替换了过后,全部相加
public static int romanToInt(String s) {
        if (s == null || s.length() == 0){
            return 0;
        }
        HashMap hashMap = new HashMap<>();
        s = s.replace("IV","1");
        hashMap.put('1',4);
        s = s.replace("IX","2");
        hashMap.put('2',9);
        s = s.replace("XL","3");
        hashMap.put('3',40);
        s = s.replace("XC","4");
        hashMap.put('4',90);
        s = s.replace("CD","5");
        hashMap.put('5',400);
        s = s.replace("CM","6");
        hashMap.put('6',900);

        hashMap.put('I',1);
        hashMap.put('V',5);
        hashMap.put('X',10);
        hashMap.put('L',50);
        hashMap.put('C',100);
        hashMap.put('D',500);
        hashMap.put('M',1000);

        int sum = 0;
        for (char x : s.toCharArray()){
            if (hashMap.containsKey(x)){
                sum += hashMap.get(x);
            }else {
                return -1;
            }
        }
        return sum;
    }

面试题191:位1的个数

按位与1,然后移位比较
public static int hammingWeight(int n) {
        int start = 1;
        int count = 0;
        int num = 0;
        while (count<=30){
            if ((start&n) == start ){
                num++;
            }
            start = start<<1;
            count++;
        }
        return num;
    }

面试题461:汉明距离

按位异或后统计为1的位数,统计为1的位数可以用n&(n-1)的次数来进行计算
public static int hammingDistance(int x, int y) {
        if (x<0||y<0){
            return -1;
        }
        int yihuo = x^y;
        int start = 1;
        int count = 0;
        int sum = 0;
        while (count<=30){
            if ((start&yihuo) == start){
                sum++;
            }
            start = start<<1;
            count++;
        }
        return sum;
    }

面试题190:颠倒二进制位

从原数的低位开始,用一个新的变量来存,每读一位分别左移和右移
public static int reverseBits(int n) {
        int ans = 0;
        for (int x = 0;x<=31;x++){
            ans = ans <<1;
            if ((n&1) == 1){
                ans += 1;
            }
            n = n>>1;
        }
        return ans;
    }

面试题118:杨辉三角

利用上一行算出下一行
public static List> generate(int numRows) {
        List> lists = new LinkedList<>();
        if (numRows<=0){
            return lists;
        }
        List level = new  ArrayList<>();
        level.add(1);
        List temp = new ArrayList<>();
        for (int x:level){
            temp.add(x);
        }
        lists.add(temp);
        if (numRows == 1){
            return lists;
        }
        for (int x = 2;x<=numRows;x++){
//            System.out.print(level);
            level.add(0,0);
            level.add(level.size(),0);
            List nexline = new ArrayList<>();
            for (int y = 0;y<=level.size()-2;y++){
                nexline.add(level.get(y)+level.get(y+1));
            }
            List add = new ArrayList<>();
            level.clear();
            for (int z:nexline){
                add.add(z);
                level.add(z);
            }
//            System.out.print(add);
            lists.add(add);
        }
        return lists;
    }

面试题20:有效的括号

用栈辅助,前半个括号进栈,读到后半个括号时取出查看是否为对应的
public static boolean isValid(String s) {
        if (s == null || s.length() == 0){
            return true;
        }
        Stack stack = new Stack<>();
        for (char x :s.toCharArray()){
            if (x == '(' || x == '[' || x =='{'){
                stack.push(x);
            }
            if (x == ')'){
                if (stack.size() == 0){
                    return false;
                }
                char temp = stack.pop();
                if (temp!='('){
                    return false;
                }
            }
            if (x == ']'){
                if (stack.size() == 0){
                    return false;
                }
                char temp = stack.pop();
                if (temp!='['){
                    return false;
                }
            }
            if (x == '}'){
                if (stack.size() == 0){
                    return false;
                }
                char temp = stack.pop();
                if (temp!='{'){
                    return false;
                }
            }

        }
        if (stack.size()!=0){
            return false;
        }
        return true;
    }

面试题268:缺失数字

利用数组的和和现在的和的差值
利用与0-n的数的异或
public static int missingNumber(int[] nums) {
        if (nums == null||nums.length == 0){
            return -1;
        }
        int sum = (0+nums.length)*(nums.length+1)/2;
        int nowsum = 0;
        for (int x:nums){
            nowsum += x;
        }
        return sum - nowsum;
    }




你可能感兴趣的:(面试)