【自我救赎--牛客网Top101 4天刷题计划】 第一天 热身运动

第一天

声明:本系列文章仅适合二刷有经验的算法er学习,以后会出详细的每一题的讲解,这里只是简单的说明思路来帮助大家快速刷完Top101,另外博主的算法全程跟着 labuladong 大佬学习,这里特此声明

1.反转链表

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ShvSiho2-1650547774607)(picture/1.png)]

解题思路

使用双指针,依次对比两个链表每个节点的值,最后合并为一个新的链表。

代码实现

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

        ListNode last = ReverseList(head.next);
        head.next.next = head;
        head.next = null;
        return last;
    }
}

2.链表内指定区间反转

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2cm44ZU1-1650547774608)(picture/2.png)]

解题思路

  1. 当 m == 1 时,问题退化为反转链表的前 n 个节点,先写出此方法
  2. 当 m != 1 时,通过递归将问题的规模向反转链表的前 n 个节点的方向靠拢

代码实现

public class Solution {
    /**
     * 
     * @param head ListNode类 
     * @param m int整型 
     * @param n int整型 
     * @return ListNode类
     */
    public ListNode reverseBetween(ListNode head, int m, int n) {
        // write code here
        if (m == 1) {
            return reverseN(head, n);
        }

        head.next = reverseBetween(head.next, m - 1, n - 1);
        return head;
    }

    ListNode successor = null;

    //反转链表的前n个节点
    public ListNode reverseN(ListNode head, int n) {
        if (n == 1) {
            successor = head.next;
            return head;
        }

        ListNode last = reverseN(head.next, n - 1);
        head.next.next = head;
        head.next = successor;
        return last;
    }
}

3.链表中的节点每k个一组进行翻转

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-69iArMLh-1650547774608)(picture/3.png)]

解题思路

  1. 先写出如上一题的链表内指定区间反转的方法,这里通过迭代的方式实现
  2. 运用递归的思想不断地翻转前 k 个节点( 不足 k 个,不需要反转)

代码实现

public class Solution {
    /**
     * 
     * @param head ListNode类 
     * @param k int整型 
     * @return ListNode类
     */
    public ListNode reverseKGroup(ListNode head, int k) {
        // write code here
        if (head == null) return null;
        // 区间 [a, b) 包含 k 个待反转元素
        ListNode a, b;
        a = b = head;
        for (int i = 0; i < k; i++) {
            // 不足 k 个,不需要反转,base case
            if (b == null) return head;
            b = b.next;
        }
        // 反转前 k 个元素
        ListNode newHead = reverse(a, b);
        // 递归反转后续链表并连接起来
        a.next = reverseKGroup(b, k);
        return newHead;
    }

    public ListNode reverse(ListNode a, ListNode b) {
        ListNode pre, cur, nxt;
        pre = null;
        cur = a;
        nxt = a;
        // while 终止的条件改一下就行了
        while (cur != b) {
            nxt = cur.next;
            cur.next = pre;
            pre = cur;
            cur = nxt;
        }
        // 返回反转后的头结点
        return pre;
    }
}

4.合并两个排序的链表

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BR5amDUY-1650547774608)(picture/4.png)]

解题思路

  1. 当两链表都不为空时,根据其 val 值得大小不同来合并,注意是用虚拟头节点来避免{}的问题出现
  2. 当某一个链表为空时(另外一个不为空),直接将其连在新链表的结尾

代码实现

public class Solution {
    public ListNode Merge(ListNode list1, ListNode list2) {
        ListNode l1 = list1, l2 = list2, dummy = new ListNode(-1), p = dummy;
        while (l1 != null && l2 != null) {
            if (l1.val > l2.val) {
                p.next = l2;
                l2 = l2.next;
            } else {
                p.next = l1;
                l1 = l1.next;
            }
            p = p.next;
        }

        if (l1 != null) {
            p.next = l1;
        }

        if (l2 != null) {
            p.next = l2;
        }

        return dummy.next;
    }
}

5.合并 k 个已排序的链表

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HRTt9De6-1650547774609)(picture/5.png)]

解题思路

  1. 使用优先堆的思想先将 lists 里面的链表头结点加入优先队列并排序
  2. 按照从小到大的顺序拿出一个节点拼接到新的头结点之后,检查此链表后面是否还有节点,如果有就加入优先队列,如果没有就略过。

代码实现

public class Solution {
    public ListNode mergeKLists(ArrayList<ListNode> lists) {
        if (lists.size() == 0) {
            return null;
        }

        ListNode dummy = new ListNode(-1), p = dummy;
        PriorityQueue<ListNode> pq = new PriorityQueue<>(
                lists.size(), (a, b) -> (a.val - b.val)
        );
        for (ListNode head : lists) {
            if (head != null) {
                pq.add(head);
            }
        }
        while (!pq.isEmpty()) {
            ListNode node = pq.poll();
            p.next = node;
            if (node.next != null) {
                pq.add(node.next);
            }
            p = p.next;
        }
        return dummy.next;
    }
}

6.判断链表是否有环

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NljZTO2P-1650547774609)(picture/6.png)]

解题思路

经典问题,记住就行,当快慢指针相遇时,链表中就出现了环

代码实现

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

7.链表中环的入口节点

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pzu9xDEY-1650547774609)(picture/7.png)]

解题思路

与上题一样的思路,只不过当快慢指针相遇之后,将 slow 指针重置回头结点,然后两个指针每次只走一步,当其再次相遇时,就是链表环的入口

代码实现

public class Solution {

    public ListNode EntryNodeOfLoop(ListNode pHead) {
        ListNode slow = pHead, fast = pHead;
        while (fast != null && fast.next != null) {
            slow = slow.next;
            fast = fast.next.next;

            if (fast == slow) {
                break;
            }
        }

        if (fast == null || fast.next == null) {
            return null;
        }

        slow = pHead;
        while (slow != fast) {
            slow = slow.next;
            fast = fast.next;
        }
        return slow;
    }
}

8.链表中倒数最后k个节点

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ob5aybe9-1650547774610)(picture/8.png)]

解题思路

依旧是快慢指针的解法,快指针先走 k 步,然后慢指针此时从头节点开始,两个指针均每次走一步,直到快指针指向 null ,此时就是链表中倒数最后k个节点

代码实现

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param pHead ListNode类 
     * @param k int整型 
     * @return ListNode类
     */
    public ListNode FindKthToTail(ListNode pHead, int k) {
        // write code here
        int n = 0;
        ListNode fast = pHead, slow = pHead;
        for (int i = 0; i < k; i++) {
            if (fast != null) {
                fast = fast.next;
            } else {
                return slow = null;
            }
        }
        while (fast != null) {
            fast = fast.next;
            slow = slow.next;
        }
        return slow;
    }
}

9.删除链表的倒数第n个节点

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bEUlYx0o-1650547774610)(picture/9.png)]

解题思路

与上一题一样,只不过这次找到倒数第 n+1 个节点然后将他后面的节点删掉即可

代码实现

public class Solution {
    /**
     * 
     * @param head ListNode类 
     * @param n int整型 
     * @return ListNode类
     */
    public ListNode removeNthFromEnd(ListNode head, int n) {
        // write code here
        ListNode dummy = new ListNode(-1);
        dummy.next = head;
        ListNode x = findFromEnd(dummy, n + 1);
        x.next = x.next.next;
        return dummy.next;
    }

    public ListNode findFromEnd(ListNode head, int k) {
        ListNode p1 = head;
        for (int i = 0; i < k; i++) {
            p1 = p1.next;
        }
        ListNode p2 = head;
        while (p1 != null) {
            p2 = p2.next;
            p1 = p1.next;
        }
        return p2;
    }
}

10.两个链表的第一个公共节点

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Szh2U5ue-1650547774610)(picture/10.png)]

解题思路

  1. 分别求出两条链表的长度,并求出两天链表的差值 k
  2. 将一个指针指向较长的那一个链表的头部,然后走 k 步,让 p1 和 p2 到达尾部的距离相同
  3. 之后两指针齐头并进直到 p1 与 p2 相等,这时会有两种情况出现
    • 1、要么是两条链表不相交,他俩同时走到尾部空指针
    • 2、要么是两条链表相交,他俩走到两条链表的相交点

代码实现

public class Solution {
    public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
        int lenA = 0, lenB = 0;
        // 计算两条链表的长度
        for (ListNode p1 = pHead1; p1 != null; p1 = p1.next) {
            lenA++;
        }
        for (ListNode p2 = pHead2; p2 != null; p2 = p2.next) {
            lenB++;
        }
        // 让 p1 和 p2 到达尾部的距离相同
        ListNode p1 = pHead1, p2 = pHead2;
        if (lenA > lenB) {
            for (int i = 0; i < lenA - lenB; i++) {
                p1 = p1.next;
            }
        } else {
            for (int i = 0; i < lenB - lenA; i++) {
                p2 = p2.next;
            }
        }
        // 看两个指针是否会相同,p1 == p2 时有两种情况:
        // 1、要么是两条链表不相交,他俩同时走到尾部空指针
        // 2、要么是两条链表相交,他俩走到两条链表的相交点
        while (p1 != p2) {
            p1 = p1.next;
            p2 = p2.next;
        }
        return p1;
    }
}

17.二分查找-1

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OI69Gw8x-1650547774610)(picture/17.png)]

解题思路

背下来

代码实现

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param nums int整型一维数组 
     * @param target int整型 
     * @return int整型
     */
    public int search(int[] nums, int target) {
        // write code here
        int lo = 0, hi = nums.length - 1 , mid;
        if(nums.length == 0){
           return -1; 
        }
        if (target < nums[lo] || target > nums[hi]) {
            return -1;
        }

        while (lo <= hi) {
            mid = lo + (hi - lo) / 2;
            if (target > nums[mid]) {
                lo = mid + 1;
            } else if (target < nums[mid]) {
                hi = mid - 1;
            } else {
                return mid;
            }
        }
        return -1;
    }
}

23.二叉树的前序遍历

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9HYVgadi-1650547774611)(picture/23.png)]

解题思路

  1. 先进行前序遍历,将遍历结果存入数组中
  2. 将遍历结果复制到int型数组中,然后返回该数组

代码实现

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param root TreeNode类 
     * @return int整型一维数组
     */
    int[] res;

    public int[] preorderTraversal(TreeNode root) {
        // write code here
        if (root == null) {
            return res = new int[0];
        }
        List<Integer> list = new ArrayList<>();
        recursionOrder(root, list);

        res = new int[list.size()];
        for (int i = 0; i < list.size(); i++) {
            res[i] = list.get(i);
        }
        return res;
    }

    public void recursionOrder(TreeNode root, List<Integer> list) {
        if (root == null) {
            return;
        }
        list.add(root.val);
        recursionOrder(root.left, list);
        recursionOrder(root.right, list);
    }
}

24.二叉树的中序遍历

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ettzghc5-1650547774611)(picture/24.png)]

解题思路

跟上题一样,记住转为int型数组就行

代码实现

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param root TreeNode类 
     * @return int整型一维数组
     */
        int[] res;

    public int[] inorderTraversal(TreeNode root) {
        // write code here
        if (root == null) {
            return res = new int[0];
        }
        List<Integer> list = new ArrayList<>();
        recursionOrder(root, list);
        res = new int[list.size()];
        for (int i = 0; i < list.size(); i++) {
            res[i] = list.get(i);
        }
        return res;
    }

    public void recursionOrder(TreeNode root, List<Integer> list) {
        if (root == null) {
            return;
        }

        recursionOrder(root.left, list);
        list.add(root.val);
        recursionOrder(root.right, list);
    }
}

25.二叉树的后序遍历

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PtNPnpQD-1650547774611)(picture/25.png)]

解题思路

跟上题一样,记住转为int型数组就行

代码实现

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param root TreeNode类 
     * @return int整型一维数组
     */
    int[] res;

    public int[] postorderTraversal(TreeNode root) {
        // write code here
        if (root == null) {
            return res = new int[0];
        }

        List<Integer> list = new ArrayList<>();
        recursionOrder(root, list);
        res = new int[list.size()];
        for (int i = 0; i < list.size(); i++) {
            res[i] = list.get(i);
        }
        return res;
    }

    public void recursionOrder(TreeNode root, List<Integer> list) {
        if (root == null) {
            return;
        }

        recursionOrder(root.left, list);
        recursionOrder(root.right, list);
        list.add(root.val);
    }
}

50.两数之和

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A6AZATVV-1650547774612)(picture/50.png)]

解题思路

纪念一下自己狂放不羁的青春,你用你的哈希表,我用我的for循环,爱咋咋地

代码实现

public class BM50 {
    public int[] twoSum(int[] numbers, int target) {
        // write code here
        int n = numbers.length;
        int[] res = {-1, -1};

        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                if (numbers[i] + numbers[j] == target) {
                    return res = new int[]{i,j};
                }
            }
        }
        return res;
    }
}

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-McZcSiVB-1650547774612)(picture/51.png)]

解题思路

HashMap的简单应用,记到把import java.util.HashMap;加进去,他没导包会报错,就是说很离谱

代码实现

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

62.斐波那切数列

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KB7Zip8h-1650547774612)(picture/62.png)]

解题思路

状态转移方程给你了,思考一下 base case 是 dp[1] = 1,直接写

代码实现

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

63.跳台阶

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iqYaEEnb-1650547774613)(picture/63.png)]

解题思路

首先要明白当你到达最后一级台阶的时候,只能是通过前一级台阶跳一步或者是前两级台阶跳两部的方式,因此可以写出状态转移方程dp[i] = dp[i - 1] + dp[i - 2]

代码实现

public class Solution {
    public int jumpFloor(int target) {
        if (target <= 1) {
            return 1;
        }

        //跳target级台阶共有dp【target】种方法
        int[] dp = new int[target + 1];
        dp[0] = 1;
        dp[1] = 1;
        for (int i = 2; i <= target; i++) {
            dp[i] = dp[i - 1] + dp[i - 2];
        }
        return dp[target];
    }
}

64.最小花费爬楼梯

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jNnY5fvR-1650547774613)(picture/64.png)]

解题思路

  1. 可以用一个dp数组记录每次爬到第i级台阶的最小花费
  2. 一开始可以从0和1任意位置,因此 dp[0] = 0 , dp[1] = 0
  3. 每次到一个台阶,只有两种情况,要么是前一级台阶向上一步,要么是前两级台阶向上两步,此时可以得到状态转移方程dp[i] = Math.min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]);

代码实现

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param cost int整型一维数组 
     * @return int整型
     */
    public int minCostClimbingStairs(int[] cost) {
        // write code here
        //dp[i] : 每次爬到第 i 阶所需要的最小花费
        int n = cost.length;
        int[] dp = new int[n + 1];
        //base case
        dp[0] = 0;
        dp[1] = 0;

        for (int i = 2; i <= n; i++) {
            dp[i] = Math.min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]);
        }
        return dp[n];
    }
}

65.最长公共子序列-2

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hkKAtH4m-1650547774613)(picture/65.png)]

解题思路

  1. 首先先计算出最长公共子序列所在的位置
  2. 然后将对应位置的字符组合成字符串的形式返回

代码实现

    public String LCS(String s1, String s2) {
        // write code here
        int len1 = s1.length();
        int len2 = s2.length();
        if (len1 == 0 || len2 == 0) {
            return "-1";
        }

        int[][] dp = new int[len1 + 1][len2 + 1];
        for (int i = 0; i <= len1; i++) {
            for (int j = 0; j <= len2; j++) {
                if (i == 0 || j == 0) {
                    dp[i][j] = 0;
                    continue;
                }
                if (s1.charAt(i - 1) == s2.charAt(j - 1)) {
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                } else {
                    dp[i][j] = Math.max(dp[i][j - 1], dp[i - 1][j]);
                }
            }
        }

        StringBuilder sb = new StringBuilder();
        int s1L = len1, s2L = len2;
        while (s1L != 0 && s2L != 0) {
            if (s1.charAt(s1L - 1) == s2.charAt(s2L - 1)) {
                sb.append(s1.charAt(s1L - 1));
                s1L--;
                s2L--;
            } else {
                if (dp[s1L - 1][s2L] > dp[s1L][s2L - 1]) {
                    s1L--;
                } else {
                    s2L--;
                }
            }
        }
        if (sb.length() == 0) {
            return "-1";
        }
        return sb.reverse().toString();
    }
}

83.字符串变形

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PKChNqv3-1650547774614)(picture/83.png)]

解题思路

  1. 将字母大小写转换后,反转整个字符串,再反转每个单词。
  2. 注意JAVA的字符串不可变,对于字符串不可变的语言,首先得把字符串转化成其他可变的数据结构.。
  3. 注意下标不要越界。

代码实现

public class Solution {

	public String trans(String s, int n) {
		StringBuilder sb=new StringBuilder(s);
		 //单词大小写反转
      	int	i=0;
      	char tmp;
      	while(i<n) {
      		tmp=sb.charAt(i);
      		if('A'<=tmp&&tmp<='Z') sb.setCharAt(i, (char) (tmp+32));
      		else if('a'<=tmp&&tmp<='z') sb.setCharAt(i, (char) (tmp-32));
      		i++;
      	}
		//翻转字符串
		reverse(sb,0,n-1);//自定义方法
		//翻转每个单词
		reverseEachWord(sb);//自定义方法
		
		return sb.toString();
	}
	private void reverse(StringBuilder sb,int left,int right) {
		while(left<right) {
			char tmp=sb.charAt(left);
			sb.setCharAt(left++, sb.charAt(right));
			sb.setCharAt(right--, tmp);
		}
	}
	private void reverseEachWord(StringBuilder sb) {
		int n=sb.length();
		int start=0,end=0;
		while(start<n) {
			//循环至单词的末尾
			while(end<n&&sb.charAt(end)!=' ') {
				end++;
			}
			reverse(sb,start,end-1);//翻转单词
			start=end+1;//更新start,去找下一个单词
			++end;
		}
	}
}

84.最长公共前缀

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sfRV3zSY-1650547774614)(picture/84.png)]

解题思路

  1. 将字符串数组看作一个二维空间,每一次从第一列开始。
  2. 确定所有字符子串中第一列字符。
  3. 逐层扫描后面每一列,遇到不同字符停止扫描。

代码实现

public class Solution {
    /**
     * 
     * @param strs string字符串一维数组 
     * @return string字符串
     */
    public String longestCommonPrefix (String[] strs) {
        // //纵向扫描
        if(strs.length==0 || strs==null){
            return "";
        }

        int rows = strs.length;
        int cols = strs[0].length();
        //开始扫描
        for(int i=0;i<cols;i++){
            char firstChar = strs[0].charAt(i);
            for(int j=1;j<rows;j++){
                if(strs[j].length()==i || strs[j].charAt(i)!=firstChar){
                    return strs[0].substring(0,i);
                }
            }
        }
        return strs[0];
    }
}

85.验证Ip地址

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fFmwsHM2-1650547774614)(picture/85.png)]

解题思路(城南亦南大神写的挺好的,我就直接搬运了)

  1. 首先需要根据分隔符,对输入字符串进行分割。含有".“的,判断是否是IPv4地址。含有”:"的,判断是否是IPv6地址。
  2. 对于IPv4的判断,分割之后,如果不是4组,返回"Neither"。如果某一组的字符不是全部由’0’-'9’范围内字符组成,返回"Neither"。如果某一组的数字大于255,或者第一位是0,而长度不止一位的,返回"Neither"。
  3. 对于IPv6的判断,分割之后,如果不是8组,返回"Neither"。如果某一组为空,或者长度大于4的,返回"Neither"。如果某一组为’0’,而该组中’0’的个数不止一个的,返回"Neither"。

代码实现

public class BM85 {
    /**
     * 验证IP地址
     * @param IP string字符串 一个IP地址字符串
     * @return string字符串
     */
    public String solve (String IP) {
        //含有"."的,判断是否是IPv4地址
        if(IP.indexOf(".")>0){
            //通过"."进行分割
            String[] strs=IP.split("\\.");
            //如果不是4组,返回"Neither"
            if(strs.length!=4) return "Neither";
            //遍历每一组
            for(int i=0;i<strs.length;i++){
                //如果某一组的字符不是全部由'0'-'9'范围内字符组成,返回"Neither"
                for(char c:strs[i].toCharArray()){
                    if(!(c>='0'&&c<='9')){
                        return "Neither";
                    }
                }
                //如果大于255,或者第一位是0,而长度不止一位的,返回"Neither"
                if(Integer.parseInt(strs[i])>255||(strs[i].charAt(0)=='0'&&strs[i].length()>1)) return "Neither";
            }
            return "IPv4";
        }
        //含有":"的,判断是否是IPv6地址
        else if(IP.indexOf(":")>0){
            //如果以":"开头,或者以":"结尾,返回"Neither"
            if(IP.charAt(0)==':'||IP.charAt(IP.length()-1)==':'){
                return "Neither";
            }
            //通过":"进行分割
            String[] strs=IP.split(":");
            //如果不是8组,返回"Neither"
            if(strs.length!=8) return "Neither";
            //遍历每一组
            for(int i=0;i<strs.length;i++){
                /* 如果某一组的字符不是全部由'0'-'9'范围内字符组成,或'a'-'f'字符,
                'A'-'F'字符范围内字符组成,返回"Neither" */
                for(char c:strs[i].toCharArray()){
                    if(!(c>='0'&&c<='9')&&!(c>='a'&&c<='f')&&!(c>='A'&&c<='F')){
                        return "Neither";
                    }
                }
                //如果某一组为空,或者长度大于4的,返回"Neither"
                if(strs[i].equals("")||strs[i].length()>4) return "Neither";

            }
            return "IPv6";
        }else{
            return "Neither";
        }
    }
}

86.大数加法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CnVI7CI5-1650547774614)(picture/86.png)]

解题思路

都用 Java 了,直接用大数类型直接过吧

代码实现

public class BM86 {
    public String solve (String s, String t) {
        BigInteger bigInteger1 = new BigInteger(s);
        BigInteger bigInteger2 = new BigInteger(t);

        return bigInteger1.add(bigInteger2).toString();
    }
}

87.合并两个有序数组

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-geA8MxtG-1650547774614)(picture/87.png)]

解题思路

  • 使用三个指针,i指向数组A的最大元素,j指向数组B的最大元素,k指向数组A空间的结尾处。
  • 从两个数组最大的元素开始遍历,直到某一个结束,每次取出较大的一个值放入数组A空间的最后,然后指针一次往前。
  • 如果数组B先遍历结束,数组A前半部分已经存在了,不用管;但是如果数组A先遍历结束,则需要把数组B剩余的前半部分依次逆序加入数组A前半部分,类似归并排序最后的步骤。

代码实现

public class BM87 {
    public void merge(int A[], int m, int B[], int n) {
        //合并
        for(int i=0;i!=n;i++){
            A[m+i] = B[i];
        }
        //排序
        Arrays.sort(A);
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值