0
点赞
收藏
分享

微信扫一扫

937. 重新排列日志文件 / 剑指 Offer II 026. 重排链表 / 剑指 Offer II 027. 回文链表

937. 重新排列日志文件【简单题】【每日一题】

思路:

代码:

class Solution {
    public String[] reorderLogFiles(String[] logs) {
        //定义nums存放数字日志
        List<String> nums = new ArrayList<>();
        //定义strs存放字母日志
        List<String> strs = new ArrayList<>();
        //遍历日志数组,将数字日志和数字日志分离
        for (String log : logs) {
            char flag = log.split(" ")[1].charAt(0);
            if (Character.isDigit(flag)){
                nums.add(log);
            }else {
                strs.add(log);
            }
        }
        //对字母日志使用lambda进行排序,根据题目要求
        //1、字母日志在内容不同时,忽略标识符后按内容字母顺序排序 --> 字母日志以第一个空格为分界点,左侧为标识符,右侧为内容,因此可将日志的内容提取出来,为 log.substring(log.indexof(' '+1))
        //2、字母日志在内容相同时,按标识符进行排序 -->因此还需要将标识符提取出来,为 log.substring(0,log.indexof(' '))
        //3、标识符和内容均提取出来之后,即可使用lambda对strs进行排序
        strs.sort((String a,String b) ->
                a.substring(a.indexOf(' ')+1).compareTo(b.substring(b.indexOf(' ')+1)) == 0 
                    ?
                a.substring(0,a.indexOf(' ')).compareTo(b.substring(0,b.indexOf(' ')))
                    :
                a.substring(a.indexOf(' ')+1).compareTo(b.substring(b.indexOf(' ')+1)));
        int i = 0,j = 0;
        //根据题目要求,将字母日志排序之后优先输出,数字日志保持原来的顺序输出
        for (int k = 0; k < logs.length; k++) {
            if (i < strs.size()){//优先将排序后的strs输出
                logs[k] = strs.get(i++);
            }else {//当strs输出完毕之后,再输出nums
                if (j < nums.size()){
                    logs[k] = nums.get(j++);
                }
            }
        }
        return logs;
    }
}

剑指 Offer II 026. 重排链表【中等题】

思路:【寻找链表中点+翻转链表+合并链表】

代码:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public void reorderList(ListNode head) {
        /**
        * 1.找出链表的中间节点
        * 2.根据中间节点将链表分为左半部分和右半部分
        * 3.将右半部分翻转
        * 4.将左半部分和右半部分交叉合并
         */
        //1.找出中间节点
        ListNode cnt = head;
        int count = 0;
        while(cnt != null){
            cnt = cnt.next;
            count++;
        }
        ListNode left = head,right = null;
        int index = 0,half = (count-1)/2;
        while(index < half){
            head = head.next;
            index++;
        }
        //2.将原链表分为左链表和右链表
        right = head.next;
        head.next = null;
        
        //3.将右链表翻转
        ListNode cur = right,reverse = null;
        while(cur != null){
            ListNode next = cur.next;
            cur.next = reverse;
            reverse = cur;
            cur = next;
        }
        right = reverse;
        //4.将左半部分与右半部分交叉合并
        ListNode nextLeft = null,nextRight = null;
        while(left != null && right != null){
            //求出left和right当前节点指针的下一个节点
            nextLeft = left.next;
            nextRight = right.next;

            //将left指针下一个指向改为right,将right下一个指向改为原本left的下一个指向
            left.next = right;
            right.next = nextLeft;

            //将left和right指针按原来顺序右移
            left = nextLeft;
            right = nextRight;
        }
    }
}

剑指 Offer II 027. 回文链表【简单题】

思路:

代码:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public boolean isPalindrome(ListNode head) {
        /**
        * 1.找出链表最中间的节点
        * 2.以中间节点为界将给定链表分为左链表和右链表
        * 3.将右链表翻转
        * 4.同时从左链表和右链表的头节点开始遍历整个链表,如果是回文链表,那么每一个遍历到的链表都应该相等
         */
        // 1.找出中间节点
        int cnt = 0;
        ListNode rightNode = head;
        while(rightNode != null){
            cnt++;
            rightNode = rightNode.next;
        }
        // System.out.println(cnt);
        ListNode left = head,right = null;
        int index = 0,half = (cnt-1)/2;
        while(index < half){
            head = head.next;
            index++;
        }
        // 2.将原链表分为左链表和右链表,考虑到原链表为奇数时左右链表长度不等,于是当为奇数时,截掉最中间那个节点
        right = head.next;
        if(cnt % 2 == 1){
            head = null;
        }else{
            head.next = null;
        }
        // 3.将右链表翻转
        ListNode cur = right,reverse = null;
        while(cur != null){
            ListNode next = cur.next;
            cur.next = reverse;
            reverse = cur;
            cur = next;
        }
        right = reverse;
        // 4.同时从头节点遍历左右两个链表,如果对应节点的值相同,则继续遍历,如果不相同则返回false,最后全部遍历结束则返回true
        while(left != null && right != null){
            if(left.val != right.val){
                return false;
            }
            left = left.next;
            right = right.next;
        }
        return true;
    }
}
举报

相关推荐

0 条评论