《剑指offer》刷题笔记(2)

反转链表

非递归解法

public class Solution {
    public ListNode ReverseList(ListNode head) {
        while(head == null)
            return null;
        ListNode pre = null;
        ListNode cur = head;
        ListNode next = null;
        while(cur != null)
        {
            next = cur.next ;
            cur.next = pre;
            pre = cur;
            cur = next;
        }
        return pre ;
    }
}

递归解法

public class Solution {
    public ListNode ReverseList(ListNode head) {
        while(head == null || head.next == null )
            return head;
        ListNode preHead = ReverseList(head.next);
        head.next.next = head;
        head.next = null;
        return preHead;
    }
}

合并链表

非递归解法

class Solution {
public:
    ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
    {
        ListNode *p = pHead1;
        ListNode *q = pHead2;
        ListNode *head = new ListNode(-1);
        ListNode *root = head;
        while( p && q )
        {
            if(p->val <= q->val)
            {
                head->next = p;
                head = head->next;
                p = p->next;
            }
            else
            {
                head->next = q;
                head = head->next;
                q = q->next;
            }
        }
        if(p)
            head->next = p;
        if(q)
            head->next = q;
        return root->next;
    }
};

递归解法

class Solution {
public:
    ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
    {
        if(pHead1 == nullptr)
            return pHead2;
        if(pHead2 == nullptr)
            return pHead1;
        ListNode *head = nullptr;
        if(pHead1->val < pHead2->val)
        {
            head = pHead1;
            head->next = Merge(pHead1->next,pHead2);
        }
        else
        {
            head = pHead2;
            head->next =  Merge(pHead1,pHead2->next);
        }
        return head;
    }
};

判断是否是子树

class Solution {
public:
    bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2)
    {
        bool result = false;
        if(pRoot1 == nullptr || pRoot2 == nullptr)
            return false;
        if(pRoot1 != nullptr && pRoot2 != nullptr)
        {
            if(pRoot1->val == pRoot2->val)
                result = HasChildtree(pRoot1,pRoot2);
            if(!result)
                result = HasSubtree(pRoot1->left,pRoot2);
            if(!result)
                result = HasSubtree(pRoot1->right,pRoot2);
        }
        return result;
    }
    bool HasChildtree(TreeNode* pRoot1,TreeNode* pRoot2)
    {
        if(pRoot2 == nullptr)
            return true;
        if(pRoot1 == nullptr)
            return false;
        if(pRoot1->val != pRoot2->val)
            return false;
        return HasChildtree(pRoot1->left,pRoot2->left) && HasChildtree(pRoot1->right,pRoot2->right);
    }
};
class Solution:
    def HasSubtree(self, pRoot1, pRoot2):
        # write code here
        def convert(p):
            if(p):
                return str(p.val) + convert(p.left) + convert(p.right)
            else:
                return ""
        return convert(pRoot2) in convert(pRoot1) if pRoot2 else False

镜像二叉树

class Solution:
    # 返回镜像树的根节点
    def Mirror(self, root):
        # write code here
        if root is None:
            return
        tmp = root.left
        root.left = root.right
        root.right = tmp
        if root.left is not None:
            self.Mirror(root.left)
        if root.right is not None:
            self.Mirror(root.right)

对称二叉树

class Solution:
    def isSymmetrical(self, pRoot):
        # write code here
        return self.getSym(pRoot,pRoot)
    def getSym(self,root1,root2):
        if root1 == None and root2 == None:
            return True
        if root1 != None and root2 == None:
            return False
        if root1 == None and root2 != None:
            return False
        if root1.val != root2.val:
            return False
        return self.getSym(root1.left,root2.right) and self.getSym(root1.right,root2.left)

顺序打印矩阵

python使用reverse()方法

# -*- coding:utf-8 -*-
class Solution:
    def printMatrix(self, matrix):
        if len(matrix) == 0:
            return matrix
        result = []
        while(matrix):
            result += matrix.pop(0)
            if not matrix or not matrix[0]:
                break
            matrix = self.getMatrix(matrix)
        print(result)

    def getMatrix(self, matrix):
        row = len(matrix)
        col = len(matrix[0])
        res = []
        for j in range(col):
            res2 = []
            for i in range(row):
                res2.append(matrix[i][j])
            res.append(res2)
        res.reverse()
        return res

常规方法,利用矩阵左上和右下的坐标进行判断,每次循环走一圈

public class Solution {
    public ArrayList<Integer> printMatrix(int [][] matrix) {
        int row = matrix.length;
        int col = matrix[0].length;
        ArrayList arrayList = new ArrayList<>();
        if(row == 0 || col == 0)
            return new ArrayList<>();
        int left = 0;
        int right = col - 1;
        int top = 0;
        int bottom = row - 1;
        while (left <= right && top <= bottom )
        {
            for(int i = left;i <= right;i++) arrayList.add(matrix[top][i]);
            for(int j = top + 1;j <= bottom;j++) arrayList.add(matrix[j][right]);
            if(top != bottom)
                for(int i = right - 1;i >= left;i--) arrayList.add(matrix[bottom][i]);
            if(left != right)
                for(int j = bottom - 1 ;j >top;j--) arrayList.add(matrix[j][left]);
            left++;
            right--;
            top++;
            bottom--;
        }
        return  arrayList;
    }
}

min栈

定义一个栈结构,并在该结构中实现一个能得到栈最小结构的min方法

使用两个栈来实现该结构,一个进栈和出栈,另外一个负责存储最小的元素

import java.util.Stack;
public class Solution
{
    Stack<Integer> stack = new Stack<>();
    Stack<Integer> minStack = new Stack<>();
    public void push(int node)
    {
        if(minStack.empty() || stack.peek() >= node)
        {
            stack.push(node);
            minStack.push(node);
        }
        else
            stack.push(node);
    }
    public void  pop()
    {
        if(stack.peek() == minStack.peek())
        {
            stack.pop();
            minStack.pop();
        }
        else
        {
            stack.pop();
        }
    }
    public int top()
    {
            return stack.peek();
    }
    public int min()
    {
        return minStack.peek();
    }
}

栈的压入,弹出序列

class Solution:
    def IsPopOrder(self, pushV, popV):
        if len(pushV) == 0 or len(popV) == 0:
            return False
        stack = []
        for i in pushV:
            stack.append(i)
            while len(stack) and stack[-1] == popV[0]:
                stack.pop()
                popV.pop(0)
        return len(stack) == 0

从上往下打印二叉树

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;

public class Solution {
    public ArrayList<Integer> PrintFromTopToBottom(TreeNode root) {
        if(root == null)
            return new ArrayList<>();
        Queue<TreeNode> queue = new LinkedList<>();
        ArrayList<Integer> arrayList =new ArrayList<>();
        queue.offer(root);
        while (!queue.isEmpty())
        {
            TreeNode top = queue.poll();
            arrayList.add(top.val);
            if (top.left != null)
                ((LinkedList<TreeNode>) queue).add(top.left);
            if (top.right !=null)
                ((LinkedList<TreeNode>) queue).add(top.right);
        }
        return arrayList;
    }
}
class Solution
{
public:
    vector<int> PrintFromTopToBottom(TreeNode* root) {
        deque<TreeNode*> que;
        vector<int> result;
        if(root == nullptr)
            return result;
        que.push_back(root);
        while(que.size())
        {
            TreeNode *top = que.front();
            que.pop_front();
            result.push_back(top->val);
            if(top->left)
                que.push_back(top->left);
            if(top->right)
                que.push_back(top->right);
        }
        return result;
    }
};

二叉搜索树的后序遍历序列

public class Solution {
    public boolean VerifySquenceOfBST(int [] sequence) {
        if(sequence.length == 0)
            return false;
        if(sequence.length ==1)
            return true;
        return find(sequence,0,sequence.length-1);
    }
    public boolean find(int[] sequence,int start,int root)
    {
        if(start>= root)
            return true;
        int i = root;
        while(i>start && sequence[i-1]>sequence[root])
            i--;
        for(int j =start;j<i;j++)
            if(sequence[j]>sequence[root])
                return false;
        return find(sequence,start,i-1) && find(sequence,i,root-1);
    }
}

二叉树中和为某一值的路径

import java.util.ArrayList;
public class Solution {
    private ArrayList<ArrayList<Integer>> arrayLists = new ArrayList<>();
    ArrayList<Integer> arrayList = new ArrayList<>();
    ArrayList<ArrayList<Integer>> FindPath(TreeNode root,int target) {
        if (root == null)
            return arrayLists;
        arrayList.add(root.val);
        target -= root.val;
        if(target == 0 && root.left == null && root.right == null)
            arrayLists.add(new ArrayList<Integer>(arrayList));
        FindPath(root.left,target);
        FindPath(root.right,target);
        arrayList.remove(arrayList.size()-1);
        return arrayLists;
    }
}
class Solution {
    vector<vector<int>> allres;
    vector<int> list;
public:
    vector<vector<int> > FindPath(TreeNode* root,int expectNumber) {
        if(root)
            getPath(root,allres,list,expectNumber);
        return allres;
    }
    void getPath(TreeNode* p,vector<vector<int>> &arrs,vector<int> &arr,int num)
    {
        arr.push_back(p->val);
        if(p->left == nullptr && p->right ==nullptr && num == p->val)
            arrs.push_back(arr);
        if(p->left)
            getPath(p->left,arrs,arr,num-p->val);
        if(p->right)
            getPath(p->right,arrs,arr,num-p->val);
        arr.pop_back();
    }
};

复杂链表复制

法1:建hashmap的方法

import java.util.HashMap;
public class Solution {
    public RandomListNode Clone(RandomListNode pHead)
    {
        HashMap<RandomListNode, RandomListNode> map = new HashMap<RandomListNode, RandomListNode>();
        RandomListNode cur = pHead;
        while (cur != null) {
            map.put(cur, new RandomListNode(cur.label));
            cur = cur.next;
        }
        cur = pHead;
        while (cur != null) {
            map.get(cur).next = map.get(cur.next);
            cur = cur.next;
        }
        RandomListNode resHead = map.get(pHead);
        cur = pHead;
        while (cur != null) {
            map.get(cur).random = map.get(cur.random);
            cur = cur.next;
        }
        return resHead;
    }
}

法2:先直接在原表上复制,然后链接random,最后从原表中拆出复制表

public class Solution {
    public RandomListNode Clone(RandomListNode pHead)
    {
         
        if(pHead == null) return null;
        RandomListNode node = pHead;
        //复制节点,并放在源节点之后
        while(node != null ){
            RandomListNode newNode = new RandomListNode(node.label);
            newNode.label = node.label;
            newNode.next = node.next;
            newNode.random = null;
            node.next = newNode;
            node = newNode.next;
        }
        //复制random指向复制后的节点
        node = pHead;
        while(node != null){
            RandomListNode newNode = node.next;
            if(node.random != null){
                newNode.random = node.random.next;
            }
            node = newNode.next;
        }
        //获取新的链表
        RandomListNode newHead = null;
        RandomListNode cloneNode = null;
        RandomListNode pNode = pHead;
        if(pNode != null){
            newHead = pNode.next;
            cloneNode = pNode.next;
            pNode.next =  cloneNode.next;
            pNode = pNode.next;
        }
         
        while(pNode != null){
            cloneNode.next = pNode.next;
            cloneNode = cloneNode.next;
            pNode.next = cloneNode.next;
            pNode = pNode.next;
        }
        return newHead;
    }
     
}

二叉搜索树与双向链表

法1:进行一遍中序遍历,然后改变结点指针

import  java.util.ArrayList;
public class Solution {
    ArrayList<TreeNode> arrayList = new ArrayList<>();
    public TreeNode Convert(TreeNode pRootOfTree) {
        if(pRootOfTree==null)
            return null;
        ArrayList<TreeNode> array = new ArrayList<>();
        midTree(pRootOfTree,array);
        for(int i=0;i<array.size()-1;i++)
        {
            array.get(i).right = array.get(i+1);
            array.get(i+1).left = array.get(i);
        }
        return array.get(0);
    }
    public void  midTree(TreeNode root,ArrayList arrayList)
    {
        if(root.left != null)
            midTree(root.left,arrayList);
        arrayList.add(root);
        if(root.right != null)
            midTree(root.right,arrayList);
    }
}

法2:保存前一个结点,但是注意pre要为全局变量

public class Solution {
    TreeNode pre = null;
    public TreeNode Convert(TreeNode pRootOfTree) {
        if(pRootOfTree == null)
            return null;
        ConvertHelp(pRootOfTree);
        TreeNode res = pRootOfTree;
        while(res.left!=null)
            res = res.left;
        return  res;
    }
    public void ConvertHelp(TreeNode root)
    {
        if(root == null)
            return;
        ConvertHelp(root.left);
        root.left = pre;
        if(pre!=null)
            pre.right = root;
        pre = root;
        ConvertHelp(root.right);
    }
}

序列化二叉树

法1

public class Solution {
    String Serialize(TreeNode root) {
        if(root ==null)
            return "#";
        StringBuilder sb = new StringBuilder();
        serializeHelper(root,sb);
        sb.deleteCharAt(sb.lastIndexOf(","));
        return  sb.toString();
    }
    public void serializeHelper(TreeNode root,StringBuilder sb)
    {
        if(root == null)
        {
            sb.append("#,");
            return;
        }
        sb.append(root.val+",");
        serializeHelper(root.left,sb);
        serializeHelper(root.right,sb);
    }
    int Index = -1;
    TreeNode Deserialize(String str) {
        if(str.length() == 0 || str == null)
            return null;
        String[] strr = str.split(",");
        return deserializeHelper(strr);
    }
    TreeNode deserializeHelper(String[] strr)
    {
        Index++;
        TreeNode node = null;
        if(strr.length>Index && !"#".equals(strr[Index]))
        {
            node = new TreeNode(Integer.valueOf(strr[Index]));
            node.left = deserializeHelper(strr);
            node.right = deserializeHelper(strr);
        }
        return node;
    }
}

法2:反序列化借助队列

import java.util.LinkedList;
import java.util.Queue;
public class Solution {
    String Serialize(TreeNode root) {
        if(root ==null)
            return "#";
        StringBuilder sb = new StringBuilder();
        serializeHelper(root,sb);
//        sb.deleteCharAt(sb.lastIndexOf(","));
        return  sb.toString();
    }
    public void serializeHelper(TreeNode root,StringBuilder sb)
    {
        if(root == null)
        {
            sb.append("#,");
            return;
        }
        sb.append(root.val+",");
        serializeHelper(root.left,sb);
        serializeHelper(root.right,sb);
    }

    TreeNode Deserialize(String str) {
        if(str == null)
            return null;
        String[] strr = str.split(",");
        Queue<String> queue = new LinkedList<>();
        for(int i = 0;i < strr.length;i++)
        {
            queue.offer(strr[i]);
        }
        return deserializeHelper(queue);
    }
    TreeNode deserializeHelper(Queue<String> queue)
    {
        String str = queue.poll();
        if(str.equals("#"))
            return null;
        TreeNode node = new TreeNode(Integer.valueOf(str));
        node.left = deserializeHelper(queue);
        node.right = deserializeHelper(queue);
        return node;
    }
}

全排列(有重复)

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Collections;

public class Solution {
    public ArrayList<String> Permutation(String str) {
        ArrayList<String> arrayList = new ArrayList<>();
        if(str != null && str.length()!=0)
        {
            permutationHelper(str.toCharArray(),0,arrayList);
        }
        Collections.sort(arrayList);
        return arrayList;
    }
    public void permutationHelper(char[] str,int Index,ArrayList<String> list)
    {
        if(Index == str.length - 1)
            list.add(String.valueOf(str));
        HashSet<Character> set = new HashSet<>();
        for(int i = Index; i<str.length; i++)
        {
            if(!set.contains(str[i]))
            {
                set.add(str[i]);
                swap(str,i,Index);
                permutationHelper(str,Index+1,list);
                swap(str,Index,i);
            }
        }
    }
    public void swap(char[] str,int i,int j)
    {
        char temp = str[i];
        str[i] = str[j];
        str[j] = temp;
    }
}

数组中出现次数超过一半的数字

打擂台的解法

package Solution;

public class Solution {
    public int MoreThanHalfNum_Solution(int [] array) {
        if (array == null || array.length == 0)
            return 0;
        int cnt = 1;
        int x = array[0];
        for (int i = 1; i < array.length; i++)
        {
            if (array[i] == x)
                cnt++;
            else
                cnt--;
            if (cnt == 0)
            {
                x = array[i];
                cnt++;
            }
        }
        //仍需要对结果进行检查,检查出不存在该数的情况
        cnt = 0;
        for(int i = 0; i < array.length; ++i)
            if(array[i] == x)
                ++cnt;
        return (cnt * 2 > array.length ? x : 0);
    }

暴力解法 : 使用hashmap

import java.util.HashMap;

public class Solution {
    public int MoreThanHalfNum_Solution(int [] array) {
        if(array.length == 1)
            return array[0];
        HashMap<Integer,Integer> hashMap = new HashMap<>();
        for(int i = 0;i < array.length;i++)
            if(!hashMap.containsKey(array[i]))
            {
                hashMap.put(array[i],1);
            }
            else
            {
                int count = hashMap.get(array[i]);
                count++ ;
                if(count>array.length/2)
                    return array[i];
                hashMap.put(array[i],count);
            }
        return 0;
    }
}

找出最小的K个数

法1:使用sort

import java.util.ArrayList;
import java.util.Arrays;

public class Solution {
    public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
        if(input == null || input.length ==0 || k < 0 || k > input.length)
            return new ArrayList<>();
        Arrays.sort(input);
        ArrayList<Integer> arrayList = new ArrayList<>();
        for(int i = 0;i < k;i++)
            arrayList.add(input[i]);
        return arrayList;
    }
}

最大子序列和

简单DP

未显示写出转移方程

public class Solution {
    public int FindGreatestSumOfSubArray(int[] array) {
        if(array == null)
            return 0;
        int max = Integer.MIN_VALUE;
        int cur = 0;
        for(int i = 0; i < array.length ; i++)
        {
            if(cur < 0)
                cur = array[i];
            else
                cur += array[i];
            if(cur > max)
                max = cur;
        }
        return max;
    }
}

显示的转移方程

public class Solution {
    public int FindGreatestSumOfSubArray(int[] array) {
       if(array == null)
           return 0;
       int res = array[0];
       int max = array[0];
       for(int i = 1; i < array.length; i++)
       {
           res = Math.max(res + array[i], array[i]);
           max = Math.max(max, res);
       }
       return max;
    }
}

把数组排成最小的数

主要考察比较函数重载

Arrays.sort的重载

import java.util.Arrays;
import java.util.Comparator;

public class Solution {
    public String PrintMinNumber(int [] numbers) {
        if(numbers == null || numbers.length < 0)
            return "";
        String[] strr = new String[numbers.length];
        for(int i = 0; i < numbers.length; i++)
            strr[i] = String.valueOf(numbers[i]);
        Arrays.sort(strr, new Comparator<String>() {
                    public int compare(String a, String b) {
                        String s1 = a + b;
                        String s2 = b + a;
                        return s1.compareTo(s2);
                    }
                }
        );
        StringBuilder sb = new StringBuilder();
        for(String i : strr)
        {
            sb.append(i);
        }
        return sb.toString();
    }
}

collections.sort重载

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;

public class Solution {
    public String PrintMinNumber(int [] numbers) {
       if(numbers == null || numbers.length < 0)
           return "";
       ArrayList<Integer> arrayList = new ArrayList<>();
       for(int i : numbers)
           arrayList.add(i);
        Collections.sort(arrayList, new Comparator<Integer>() {
            public int compare(Integer a, Integer b)
            {
                String s1 = a + "" + b ;
                String s2 = b + "" + a;
                return  s1.compareTo(s2);
            }
        });
        String s = "";
        for(int i : arrayList)
            s += i;
        return s;
    }
}

第index个丑数

丑数指的是只含有2,3,5质数的数,默认第一个丑数是1

import java.util.ArrayList;

public class Solution {
    public int GetUglyNumber_Solution(int index) {
        if(index <= 0)
            return 0;
        ArrayList<Integer> list = new ArrayList<>();
        list.add(1);
        int num = 1;
        int i2 = 0,i3 = 0,i5 = 0;
        while(num < index)
        {
            int a2 = list.get(i2) * 2;
            int a3 = list.get(i3) * 3;
            int a5 = list.get(i5) * 5;
            int min = Math.min(a2,Math.min(a3,a5));
            list.add(min);
            if(min == a2) i2++;
            if(min == a3) i3++;
            if(min == a5) i5++;
            num++;
        }
        return list.get(index - 1);
    }
}

找出第一个只出现一次的字

import java.util.HashMap;

public class Solution {
    public int FirstNotRepeatingChar(String str)
    {
        if(str == null || str.length() <= 0)
            return -1;
        HashMap<Character,Integer> map = new HashMap<>();
        for(int i = 0; i < str.length(); i++)
            if(!map.containsKey(str.charAt(i)))
                map.put(str.charAt(i),1);
            else
            {
                int num = map.get(str.charAt(i));
                num++;
                map.put(str.charAt(i),num);
            }
        for(int i = 0;i < str.length();i++)
        {
            if(map.get(str.charAt(i)) == 1)
                return i;
        }
        return -1;
    }
}

逆序对

归并排序

注意cur的计算,是mid - p1 + 1

public class Solution
{
    int cur = 0;
    public int InversePairs(int [] array) {
        if (array==null || array.length<=0)
            return 0;
        devide(array, 0, array.length - 1);
        return cur;
    }
    public void devide(int [] array, int start, int end)
    {
        if( start >= end)
            return;
        int mid = (start + end)>>1;
        devide(array,start,mid);
        devide(array, mid+1,end);
        merge(array,start,mid,end);
    }
    public void merge(int[] array, int start, int mid, int end)
    {
        int [] help = new int[end - start + 1];
        int p1 = start;
        int p2 = mid + 1;
        int k = 0;
        while(p1 <= mid && p2 <= end)
        {
            if(array[p1] <= array[p2])
                help[k++] = array[p1++];
            else
            {
                help[k++] = array[p2++];
                cur = (cur + mid - p1 + 1)%1000000007; //%1000000007防止大整数
            }
        }
        while(p1 <= mid)help[k++] = array[p1++];
        while(p2 <= end)help[k++] = array[p2++];
        for(int i = 0; i < help.length; i++)
        {
            array[start + i] = help[i];
        }
    }

}

另一种写法

import java.util.ArrayList;

public class Solution
{
    int res = 0;
    public int InversePairs(int [] array)
    {
        if(array == null || array.length<=0)
            return 0;
        return merge(array,0,array.length-1);
    }
    public int merge(int [] a, int l, int r)
    {
        if(l>=r)
            return 0;
        int m = (l + r)>>1;
        res = merge(a,l,m) + merge(a,m+1,r);
        int i = l;
        int j = m+1;
        ArrayList<Integer> list = new ArrayList<>();
        while(i<=m && j<=r)
            if(a[i] <= a[j])list.add(a[i++]);
            else
            {
                list.add(a[j++]);
                res = (res + m -i + 1)%1000000007;
            }
        while(i<=m) list.add(a[i++]);
        while(j<=r) list.add(a[j++]);
        for(int k=0;k<list.size();k++)
        {
            a[l+k] = list.get(k);
        }
        return res;
    }
}

找到两个链表的公共节点

public class Solution {
    public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
        if(pHead1 == null || pHead2 == null)
            return null;
        int l1 = 0,l2 = 0;
        ListNode p1 = pHead1;
        ListNode p2 = pHead2;
        while(p1 != null)
        {
            l1++;
            p1 = p1.next;
        }
        while(p2 != null)
        {
            l2++;
            p2 = p2.next;
        }
        p1 = pHead1;
        p2 = pHead2;
        if(l1 >= l2)
        {
            while((l1-l2) != 0)
            {
                p1 = p1.next;
                l1--;
            }
        }
        else
        {
            while((l2-l1) != 0)
            {
                p2 = p2.next;
                l2--;
            }
        }
        while(p1 != null || p2 != null)
        {
            if(p1.val == p2.val)
                return p1;
            p1 = p1.next;
            p2 = p2.next;
        }
        return null;
    }
}

还可以利用栈

import java.util.Stack;

public class Solution {
    public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
        if(pHead1 == null || pHead2 == null)
            return null;
        Stack<ListNode> stack1 = new Stack<>();
        Stack<ListNode> stack2 = new Stack<>();
        ListNode p1 = pHead1;
        ListNode p2 = pHead2;
        while(p1 != null)
        {
            stack1.push(p1);
            p1 = p1.next;
        }
        while(p2 != null)
        {
            stack2.push(p2);
            p2 = p2.next;
        }
        ListNode comNode = null;	//必须定义comNode用来保存公共节点,因为如果两个链表万千相同,会导致两个栈都pop到空
        while(!stack1.isEmpty() && !stack2.isEmpty() && stack1.peek().val == stack2.peek().val)	
        {
            comNode = stack1.pop();
            stack2.pop();
        }
        return comNode;
    }
}

数字在排序数组中出现的次数

class Solution {
    public int GetNumberOfK(int[] nums, int k) {
        if(nums.length <=0)
            return 0;
        int length = nums.length;
        int last = getLastNum(nums,k,0,length-1);
        int fast = getFastNum(nums,k,0,length-1);
        if(fast == -1 && last == -1)
            return 0;
        else
        {
            return  last - fast + 1;
        }
    }
    public int getFastNum(int[] nums, int k, int l, int r)
    {
        while(l <= r)
        {
            int m = (l + r)>>1;
            if(nums[m] > k)
                r = m - 1;
            else if(nums[m] < k)
                l = m + 1;
            else if(nums[m] == k && m != 0 && nums[m - 1] == k)
                r = m - 1;
            else
                return m;
        }
        return -1;
    }
    public int getLastNum(int[] nums, int k, int l, int r)
    {
        while(l <= r)
        {
            int m = (l + r)>>1;
            if(nums[m] > k)
                r = m - 1;
            else if(nums[m] < k)
                l = m + 1;
            else if(nums[m] == k && m + 1 != nums.length && nums[m + 1] == k)
                l = m + 1;
            else
                return m;
        }
        return -1;
    }
}

变体1:找寻连续数字中缺少的部分

class Solution
{
    public int findNum(int []nums)
    {
        if(nums.length <= 0)
            return -1;
        if(nums[0] != 0)
            return 0;
        int l = 0;
        int r = nums.length - 1;
        return helper(nums,l,r);
    }
    public  int helper(int []nums,int l,int r)
    {
        while (l <= r)
        {
            int m = (l + r)>>1;
            if(nums[m] == m)
                l = m + 1;
            else
                if(nums[m] != m && m!=0 && nums[m-1] == (m-1))
                    return m;
            else
                r = m - 1;
        }
        return -1;
    }
}

变体2:在顺序数字中找到某数和下标相同(logn)

class Solution
{
    public int findNum(int[] nums)
    {
        if(nums.length <= 0 )
            return -1;
        if(nums[0] == 0)
            return 0;
        return helper(nums);
    }
    public int helper(int[] nums)
    {
        int l = 0;
        int r = nums.length-1;
        while(l <= r)
        {
            int m = (l + r)>>1;
            if(nums[m] == m)
                return m;
            else if(nums[m] > m)
                r = m - 1;
            else
                l = m + 1;
        }
        return -1;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值