刷题笔记--牛客在线算法题📝(2)

265 阅读3分钟

算法题笔记

Q11 翻转链表

Q 本题可通过双指针进行解决,对原始链表中的节点一个一个翻转,最后返回最后一个翻转的节点即可。

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

    ListNode(int val) {
        this.val = val;
    }
}*/
public class Solution {
  /**
     * 翻转链表
     * @param head
     * @return
     */
    public ListNode ReverseList(ListNode head) {
        ListNode prev = null;
        ListNode cur = head;
        while (cur != null) {
            ListNode nxt = cur.next;
            cur.next = prev;
            if (nxt == null) {
                return cur;
            }else {
                prev = cur;
                cur = nxt;
            }
        }
        return null;
    }
}

Q12 二叉树所有根节点到叶子结点路径值为Tar的路径

Q 典型的二叉树🌲递归问题,直接借助dfs即可解决。方法dfs带有当前路径上的值,以及当前路径权值。

首先判断当前节点是不是leaf node。如果是叶子节点的话,进一步判断当前路径和是否与Tar相等,相等的话加入结果集中。树空间所有路径走完即可得到最后结果,具体代码如下

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 * }
 */

public class Solution {
/**
     *
     * @param root TreeNode类
     * @param sum int整型
     * @return int整型ArrayList<ArrayList<>>
     */
    public ArrayList<ArrayList<Integer>> pathSum (TreeNode root, int sum) {
        // write code here
        ArrayList<ArrayList<Integer>> res = new ArrayList<>();
        if (root == null) {
            return res;
        }
        ArrayList<Integer> now = new ArrayList<>();
        dfs(root,now,res,0,sum);
        return res;
    }

    private void dfs(TreeNode p,ArrayList<Integer> now,
                     ArrayList<ArrayList<Integer>> res,
                     int val,int tar) {
        if (p == null) {
            return;
        }
        if (p.left == null && p.right == null) {
            // leaf node
            if (val+p.val == tar) {
                now.add(p.val);
                res.add(new ArrayList<>(now));
                now.remove(now.size()-1);
            }
            return;
        }
        // not leaf node
        now.add(p.val);
        dfs(p.left,now,res,val+p.val,tar);
        dfs(p.right,now,res,val+p.val,tar);
        now.remove(now.size()-1);
    }
}

Q13 两个栈模拟一个队列

十分典型的算法题,在面试pdd、网易的时候都问到了。

算法较为简单。主要思想是,stack1用来填充数据,每次新数据都压入stack1中。stack2用来帮助stack1进行弹出数据过程的过渡,步骤就是先把stack1中除了栈底元素外的所有元素压入stack2中,然后把栈底作为res弹出来,然后把stack2中元素远路弹回stack1中即可,返回res

具体代码如下:

import java.util.Stack;

public class Solution {
    Stack<Integer> stack1 = new Stack<Integer>();
    Stack<Integer> stack2 = new Stack<Integer>();
    
    public void push(int node) {
        stack1.push(node);
    }
    
    public int pop() {
        if(stack1.isEmpty()) {
            return -1;
        }
        while(stack1.size() > 1) {
            stack2.add(stack1.pop());
        }
        int res = stack1.pop();
        while(!stack2.isEmpty()) {
            stack1.add(stack2.pop());
        }
        return res;
    }
}

Q14 字符串排列

因为要考虑最后的输出是按照顺序的,但是数据量大的时候最后再排序容易TLE。我们只需要dfs的时候保证先dfs小的字母即可保证最后输出的字符串一定是从小到大的。最后注意去重即可,具体代码如下。

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
public class Solution {
Set<String> seen = new HashSet<>();
    public ArrayList<String> Permutation(String str) {
        ArrayList<String> res = new ArrayList<>();
        char[] c = str.toCharArray();
        Arrays.sort(c);
        int len = c.length;
        int[] memo = new int[len];
        dfs(res,c,memo,new char[len],0);
        return res;
    }

    private void dfs(ArrayList<String> res,char[] strArr,
                     int[] memo,char[] now,
                     int len) {
        if (len == memo.length) {
            String r = String.valueOf(now);
            if (!seen.contains(r)) {
                res.add(r);
                seen.add(r);
            }
            return;
        }
        for (int i=0;i<memo.length;i++) {
            if (memo[i] == 0) {
                now[len] = strArr[i];
                memo[i] = 1;
                dfs(res,strArr,memo,now,len+1);
                memo[i] = 0;
            }
        }
    }

}

Q5 数组第K大的数

本题为LeetCode上经典算法题,面试常问的算法。有许多解法,面试中较为常考的一般是快速选择方法,还可以使用等方法~

快速选择法的核心思想同快速排序一样~

下面参考文章讲了很多不同方法,值得学习:

ref: leetcode-cn.com/problems/kt…

import java.util.*;

public class Solution {
public int findKth(int[] a, int n, int K) {
        // write code here
        // 1 big => n small => n-1 idx
        // 2 big => n-1 small =>. n-2 idx
        // K big => n+1-K small => n-K idx
        quickPick(a,0,n-1,n-K);
        return a[n-K];
    }

    private void quickPick(int[] arr,int l,int r,int k) {
        int lcur = l;
        int rcur = r;
        int pivot = arr[l];
        while (lcur < rcur) {
            while (lcur < rcur && arr[rcur]>=pivot) rcur--;
            while (lcur < rcur && arr[lcur]<=pivot) lcur++;
            if (lcur < rcur) {
                int temp = arr[lcur];
                arr[lcur] = arr[rcur];
                arr[rcur] = temp;
            }
        }
        arr[l] = arr[lcur];
        arr[lcur] = pivot;
        if (lcur == k) {
            return;
        }else if (lcur < k) {
            quickPick(arr,lcur+1,r,k);
        }else {
            // lcur > k
            quickPick(arr,l,lcur-1,k);
        }
    }
}

Q6 买卖股票的最好时机

股票问题是LeetCode上的一个经典动态规划类型问题。

本题是股票问题的一个最简单问题,用户只可以交易一次。只需判断当前价格之前最低的价格是多少,然后判断是否比max变量记录的值要大即可,初始化max=0

具体代码如下:

import java.util.*;


public class Solution {
     /**
     *
     * @param prices int整型一维数组
     * @return int整型
     */
    public int maxProfit (int[] prices) {
        // write code here
        if (prices.length <= 1){
            return 0;
        }
        int res = 0;
        int prev = prices[0];
        for (int i=1;i<prices.length;i++) {
            res = Math.max(res,prices[i]-prev);
            prev = Math.min(prev,prices[i]);
        }
        return res;
    }
}

Q7 旋转数组查找某值

经典题,具体代码如下

import java.util.*;


public class Solution {
/**
     *
     * @param A int整型一维数组
     * @param target int整型
     * @return int整型
     */
    public int search (int[] A, int target) {
        // write code here
        int len = A.length;
        return helper(A,0,len-1,target);
    }
    private int helper(int[] arr,int l,int r,int tar) {
        if(l > r) return -1;
        if (l == r) {
            return arr[l] == tar ? l:-1;
        }
        int mid = (l+r)>>1;
        if (arr[mid] == tar) {
            return mid;
        }else{
            int lp = helper(arr,mid+1,r,tar);
            int rp = helper(arr,l,mid-1,tar);
            return lp == -1 ? rp:lp;
        }
    }
}

Q8 Fibonacci数列

经典斐波那契数列问题,可用dfs或者dp 具体代码如下:

public int Fibonacci(int n) {
        if (n<=1) return n;
        int[] dp = new int[n+1];
        dp[0] = 0;
        dp[1] = 1;
        for (int i=2;i<=n;i++) {
            dp[i] = dp[i-1]+dp[i-2];
        }
        return dp[n];
    }
    ```