算法:反转系列

LC 7题:整数反转(比如 -123)

public class LC07 {
    public int reverse(int x) {
        long res = 0; //用int的话翻转后可能溢出,比如1999999999(-2147483648~2147483647)
        while (x != 0) {
            res = res * 10 + x % 10; //x=123,x%10=3, x/=10  x为12
            x /= 10;
            //当它的逆序整型数溢出的话,返回 0
            if (res > Integer.MAX_VALUE || res < Integer.MIN_VALUE) {
                res = 0;
            }
        }
        return (int) res;
    }
    
	//方法二:不用long
    public int reverse2(int x) {
        int res = 0;
        while (x != 0) {
            int temp = res * 10 + x % 10;
            if ((temp - x % 10) / 10 != res) { //相等表示未发生溢出
                return 0;
            }
            res = temp;
            x /= 10;
        }
        return res;
    }
}

  

剑指offer44:句子里单词顺序反转,单词本身不变

public class T_44_ReverseSentence {
    public String ReverseSentence(String str) {
        if (str.trim().length() == 0) {
            return str;
        }
        String[] word = str.split(" ");
        StringBuilder res = new StringBuilder();
        for (int i = word.length - 1; i > 0; i--) {
            res.append(word[i]).append(" "); //注意写法
        }
        res.append(word[0]);
        return res.toString();
    }
}

  

LC 557:句子里的单词反转,句子整体顺序不变

  • StringBuilder 的 append 方法输入的是String类型
  • StringBuilder 内部有 reverse 方法
  • trim 表示去掉字符串两端的多余空格
public class LC557 {
    public String reverseWords(String s) {
        String[] words = s.split(" ");
        StringBuilder res = new StringBuilder();
        for (String word : words) {

            res.append(new StringBuilder(word).reverse().toString()).append(" ");
        }
        return res.toString().trim(); 
    }
}

  

剑指offer 15:反转链表

public class T_15_ReverseList {
    public ListNode ReverseList(ListNode head) {
   		ListNode pre = null;
        ListNode cur = head;
        while (cur != null) {
            ListNode next = cur.next;
            cur.next = pre;
            pre = cur;
            cur = next;
        }
        return pre;
    }
    
        //递归写法
    public ListNode ReverseListRec(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }
        ListNode p = ReverseListRec(head.next);
        head.next.next = head;
        head.next = null;
        return p;
    }
    
    public class ListNode {
        int val;
        ListNode next;
        public ListNode(int val) {
            this.val = val;
        }
    }
}

LC 92:反转 m 到 n 范围的链表

  • 1 ≤ m ≤ n ≤ 链表长度。
  • 输入: 1->2->3->4->5->NULL, m = 2, n = 4
  • 输出: 1->4->3->2->5->NULL
public class LC92 {
    public ListNode reverseBetween(ListNode head, int m, int n) {
        if (head == null) {
            return null;
        }
        ListNode cur = head;
        ListNode pre = null;
        while (m > 1) {
            pre = cur;
            cur = cur.next;
            m--;
            n--;
        }
        ListNode con = pre;
        ListNode tail = cur;
        ListNode next;
        while (n > 0) {
            next = cur.next;
            cur.next = pre;
            pre = cur;
            cur = next;
            n--;
        }
        if (con != null) {
            con.next = pre;
        } else {
            head = pre;
        }
        tail.next = cur;
        return head;
    }
}

  

LC 344题:反转字符串(双指针法)

  • 输入:[“h”,“e”,“l”,“l”,“o”]
  • 输出:[“o”,“l”,“l”,“e”,“h”]
public class LC344 {
    public void reverseString(char[] s) {
        int i = 0;
        int j = s.length - 1;
        while (i < j) {
            char temp = s[i];
            s[i] = s[j];
            s[j] = temp;
            i++;
            j--;
        }
    }
}

  

LC 345题:反转字符串中的元音字母(aeiou,AEIOU,双指针法)

public class LC345 {
    public String reverseVowels(String s) {
        if (s == null) {
            return null;
        }
        HashSet<Character> vowels = new HashSet<>(Arrays.asList('a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U'));
        int i = 0;
        int j = s.length() - 1;
        char[] res = new char[s.length()];
        while (i <= j) {
            char ci = s.charAt(i);
            char cj = s.charAt(j);
            if (!vowels.contains(ci)) {
                res[i++] = ci;
            } else if (!vowels.contains(cj)) {
                res[j--] = cj;
            } else {
                res[i++] = cj;
                res[j--] = ci;
            }
        }
        return String.valueOf(res);
    }
}

  

LC 541题:给定一个字符串和一个整数 k,你需要对从字符串开头算起的每个 2k 个字符的前k个字符进行反转。如果剩余少于 k 个字符,则将剩余的所有全部反转。如果有小于 2k 但大于或等于 k 个字符,则反转前 k 个字符,并将剩余的字符保持原样。

思路:反转k个,跳过k个,最后剩余的不够k个,全部反转

public class LC541 {
    public String reverseStr(String s, int k) {
        char[] arr = s.toCharArray();
        int i = 0;
        while (i < arr.length) {
            if (i + 2 * k <= arr.length) {
                //反转i ~ i+k
                reverseArr(arr, i, i + k - 1);
            } else if (i + k <= arr.length) {
                //反转 i ~ i+k
                reverseArr(arr, i, i + k - 1);
            } else { // if(i + k > arr.length)
                //反转 i ~ arr.length - 1
                reverseArr(arr, i, arr.length - 1);
            }
            i += 2 * k;
        }
        return String.valueOf(arr);
    }

    private void reverseArr(char[] arr, int from, int end) {
        for (int i = from, j = end; i < j; i++, j--) {
            char t = arr[i];
            arr[i] = arr[j];
            arr[j] = t;
        }
    }
}

  

LC 917:仅仅反转字母,字符位置不动

  • 输入:“a-bC-dEf-ghIj”
  • 输出:“j-Ih-gfE-dCba”
public class LC917 {
    public String reverseOnlyLetters(String s) {
        StringBuilder res = new StringBuilder();
        int j = s.length() - 1;
        for (int i = 0; i < s.length(); i++) {
            if (Character.isLetter(s.charAt(i))) {
                while (!Character.isLetter(s.charAt(j))) {
                    j--;
                }
                res.append(s.charAt(j--));
            } else {
                res.append(s.charAt(i));
            }
        }
        return res.toString();
    }
}

  

LC 1190:反转每对括号间的子串。结果中不包含任何括号。

输入:s = “(u(love)i)”
输出:“iloveu”
思路:用栈来记录左括号。

public class LC1190 {
    public String reverseParentheses(String s) {
        StringBuilder sb = new StringBuilder();
        Stack<Integer> stack = new Stack<>();
        char[] arr = s.toCharArray();

        for (int i = 0; i < arr.length; i++) {
            if (arr[i] == '(') {
                stack.push(i);
            }
            if (arr[i] == ')') {
                reverse(arr, stack.pop() + 1, i - 1);
            }
        }
        for (char c : arr) {
            if (c != ')' && c != '(') {
                sb.append(c);
            }
        }
        return sb.toString();
    }

    private void reverse(char[] arr, int l, int r) {
        while (r > l) {
            char tmp = arr[l];
            arr[l] = arr[r];
            arr[r] = tmp;
            r--;
            l++;
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值