剑指Offer系列
剑指 Offer 04. 二维数组中的查找
注:此题与Leetcode 240相同
public boolean findNumberIn2DArray(int[][] matrix, int target) {
if(matrix.length==0){
return false;
}
int right=matrix[0].length-1;
int top=0;
while (top<matrix.length&&right>=0){
if (matrix[top][right]==target){
return true;
}
if(matrix[top][right]<target){
top++;
}
else{
right--;
}
}
return false;
}
剑指 Offer 09. 用两个栈实现队列(Solved)
class CQueue {
public static Stack<Integer> stack1;
public static Stack<Integer> stack2;
public CQueue() {
stack1=new Stack<>();
stack2=new Stack<>();
}
public void appendTail(int value) {
stack1.push(value);
}
public int deleteHead() {
if (stack2.isEmpty()){
while (!stack1.isEmpty()){
stack2.push(stack1.pop());
}
}
if (stack2.isEmpty()){
return -1;
}
return stack2.pop();
}
}
剑指 Offer 10- I. 斐波那契数列(Solved)
public int fib(int n) {
if (n==1){
return 1;
}
if(n==2){
return 1;
}
int before=1;
int before_2=1;
int res=0;
for (int i=3;i<=n;i++){
res=(before_2+before)%1000000007;
before_2=before;
before=res;
}
return res;
}
剑指 Offer 10- II. 青蛙跳台阶问题(Solved)
public int numWays(int n) {
if(n==0){
return 1;
}
if(n==1){
return 1;
}
if(n==2){
return 2;
}
int before2=1;
int before=2;
int res = 0;
for (int i=3;i<=n;i++){
res=(before+before2)%1000000007;
before2=before;
before=res;
}
return res;
}
剑指 Offer 21. 调整数组顺序使奇数位于偶数前面
public int[] exchange(int[] nums) {
int curr=0,odd=nums.length-1;
while (curr<odd){
if(nums[curr]%2==0){
int tmp=nums[curr];
nums[curr]=nums[odd];
nums[odd]=tmp;
odd--;
}
else{
curr++;
}
}
return nums;
}
剑指 Offer 22. 链表中倒数第k个节点
public ListNode getKthFromEnd(ListNode head, int k) {
ListNode fast=head;
ListNode slow=head;
for(int i=1;i<=k;i++){
if(fast==null){
return null;
}
fast=fast.next;
}
while(fast!=null){
fast=fast.next;
slow=slow.next;
}
return slow;
}
剑指 Offer 26. 树的子结构
public boolean isSubStructure(TreeNode A, TreeNode B) {
if (A==null&&B==null){
return true;
}
if (A == null||B==null){
return false;
}
if (A.val==B.val){
return (isSameTree(A.left,B.left)&&isSameTree(A.right,B.right))||isSubStructure(A.left,B)||isSubStructure(A.right,B);
}
return isSubStructure(A.left,B)||isSubStructure(A.right,B);
}
public boolean isSameTree(TreeNode nodeA,TreeNode nodeB){
if (nodeA==null&&nodeB==null){
return true;
}
if (nodeA == null){
return false;
}
if(nodeB==null){
return true;
}
if (nodeA.val==nodeB.val){
return isSameTree(nodeA.left,nodeB.left)&&isSameTree(nodeA.right,nodeB.right);
}
return false;
}
剑指 Offer 27. 二叉树的镜像
注:此题与Leetcode 224相同
public TreeNode mirrorTree(TreeNode root) {
bfs(root);
return root;
}
public void bfs(TreeNode node){
if (node==null){
return ;
}
TreeNode temp=node.left;
node.left=node.right;
node.right=temp;
bfs(node.left);
bfs(node.right);
}
剑指 Offer 29. 顺时针打印矩阵
注:此题与Leetcode 54相同
def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
if not len(matrix):
return []
res = list()
top, bottom, left, right = 0, len(matrix), 0, len(matrix[0])
while left < right and top < bottom:
i = left
while i < right:
res.append(matrix[top][i])
i += 1
top += 1
i = top
while i < bottom:
res.append(matrix[i][right-1])
i += 1
right -= 1
if not (left< right and top<bottom):
break
i = right-1
while i >= left:
res.append(matrix[bottom-1][i])
i -= 1
bottom -= 1
i = bottom-1
while i >= top:
res.append(matrix[i][left])
i -= 1
left += 1
return res
剑指 Offer 36. 二叉搜索树与双向链表
class Solution {
public static Node prev=null;
public static Node head;
public Node treeToDoublyList(Node root) {
if(root==null){
return null;
}
// head --> Pointer to head node of created doubly linked list
head=null;
prev=null;
inOrderView(root);
head.left=prev;
prev.right=head;
return head;
}
public void inOrderView(Node root){
if(root==null){
return;
}
inOrderView(root.left);
if(prev==null){
head=root;
}
else{
prev.right=root;
root.left=prev;
}
prev=root;
inOrderView(root.right);
}
}
剑指 Offer 40. 最小的k个数
public int[] getLeastNumbers(int[] arr, int k) {
PriorityQueue<Integer> nums=new PriorityQueue<>(arr.length, Integer::compare);
for(var val:arr){
nums.offer(val);
}
int[] res=new int[k];
for (int i=0;i<k;i++){
res[i]=nums.poll();
}
return res;
}
}
剑指 Offer 42. 连续子数组的最大和
public int maxSubArray(int[] nums) {
int max=Integer.MIN_VALUE;
int AnotherMax=0;
int currSum=0;
for (int num : nums) {
max = Math.max(max, num);
currSum = Math.max(currSum + num, 0);
AnotherMax = Math.max(AnotherMax, currSum);
}
if(max<0){
return max;
}
return AnotherMax;
}
剑指 Offer 48. 最长不含重复字符的子字符串
与leetcode 第三题相同
public int lengthOfLongestSubstring(String s) {
int left=0;
int right=0;
int[] alphabet=new int[256];
int currLen=0;
int maxLen=0;
char[] sArr=s.toCharArray();
while (right<s.length()){
if (alphabet[sArr[right]]==0){
currLen++;
maxLen=Math.max(currLen,maxLen);
alphabet[sArr[right]]++;
}
else{
while (alphabet[sArr[right]]>0){
alphabet[sArr[left]]--;
currLen--;
left++;
}
alphabet[sArr[right]]++;
currLen++;
}
right++;
}
return maxLen;
}
剑指 Offer 51. 数组中的逆序对
public class Solution {
//合并函数
private int mergeAndCount(int[] arr, int l, int m, int r)
{
int[] leftArr=Arrays.copyOfRange(arr,l,m+1);
int[] rightArr=Arrays.copyOfRange(arr,m+1,r+1);
int i=0,j=0,arr_idx=l,counterOrders=0;
while (i<leftArr.length&&j<rightArr.length){
if(leftArr[i]<=rightArr[j]){
arr[arr_idx]=leftArr[i];
i++;
arr_idx++;
}else{
arr[arr_idx]=rightArr[j];
j++;
arr_idx++;
counterOrders+=((m+1)-(l+i));
}
}
while (i<leftArr.length){
arr[arr_idx]=leftArr[i];
arr_idx++;
i++;
}
while (j<rightArr.length){
arr[arr_idx]=rightArr[j];
arr_idx++;
j++;
}
return counterOrders;
}
// 归并排序
private int mergeSortAndCount(int[] arr, int l, int r)
{
int count=0;
if(l<r){
int mid =(l+r)>>1;
count+=mergeSortAndCount(arr,l,mid);
count+=mergeSortAndCount(arr,mid+1,r);
count+=mergeAndCount(arr,l,mid,r);
}
return count;
}
public int reversePairs(int[] nums) {
return mergeSortAndCount(nums, 0, nums.length-1);
}
}
剑指 Offer 52. 两个链表的第一个公共节点
注:此题与Leetcode 160相同
ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if(headA==null|headB==null){
return null;
}
var curr_a=headA;
var curr_b=headB;
while (curr_a!=null&&curr_b!=null){
curr_a=curr_a.next;
curr_b=curr_b.next;
}
if (curr_a==null){
curr_a=headB;
}
if (curr_b==null){
curr_b=headA;
}
while (curr_a!=null&&curr_b!=null){
curr_a=curr_a.next;
curr_b=curr_b.next;
}
if (curr_a==null){
curr_a=headB;
}
if (curr_b==null){
curr_b=headA;
}
while (curr_a!=curr_b){
curr_a=curr_a.next;
curr_b=curr_b.next;
}
return curr_a;
}
剑指 Offer 54. 二叉搜索树的第k大节点(Solved)
class Solution {
public static int overall_k=0;
public static int res;
public int kthLargest(TreeNode root, int k) {
overall_k=k;
res=0;
reverseBfs(root);
return res;
}
public void reverseBfs(TreeNode root){
if(root==null){
return;
}
reverseBfs(root.right);
overall_k--;
if(overall_k==0){
res=root.val;
}
reverseBfs(root.left);
}
}
剑指 Offer 62. 圆圈中最后剩下的数字(josephus problem)
数学法
public int lastRemaining(int n, int m) {
// Initialize variables i and ans with 1 and 0 respectively.
int i = 1, ans = 0;
// Run a while loop till i <= N
while (i <= n) {
// Update the Value of ans and Increment i by 1
ans = (ans + m) % i;
i++;
}
// Return required answer
return ans;
}
面试题61. 扑克牌中的顺子
方法1
public boolean isStraight(int[] nums) {
Arrays.sort(nums);
int idx=0;
while(nums[idx]==0&&idx<nums.length){
idx++;
}
int zeros=idx;
if (idx==nums.length){
return true;
}
int prev=nums[idx];
idx++;
while(idx<nums.length){
int gap=nums[idx]-prev-1;
if(gap<0){
return false;
}
if(gap>0){
zeros-=gap;
}
if(zeros<0){
return false;
}
prev=nums[idx];
idx++;
}
return true;
}
方法2
HashSet<Integer> res=new HashSet<>();
int min=13;
int max=0;
for (int val:nums){
if (val==0){
continue;
}
if (res.contains(val)){
return false;
}
res.add(val);
if (val>max){
max=val;
}
if (val<min){
min=val;
}
}
return max-min-4<=0;
}