LeetCode 24-30

24. 两两交换链表中的节点

class Solution {
    public ListNode swapPairs(ListNode head) {
        ListNode dummy = new ListNode(-1);
        ListNode cur = dummy, pre = head, tail = null;
        cur.next = head;
        while(pre!= null && pre.next!= null) {
            tail = pre.next;
            ListNode nextHead = tail.next;//临时存一下下剩下需要交换的链表
            cur.next = tail;
            tail.next = pre;
            cur = cur.next.next;
            pre = nextHead;
            cur.next = nextHead;//连起剩下还没有交换的链表            
        }
        return dummy.next;
    }
    public ListNode swapPairs(ListNode head) {
        ListNode dummy = new ListNode(-1);
        dummy.next = head;
        for(ListNode pre = head, tail = null, cur = dummy; pre!= null && pre.next!= null;) {
            tail = pre.next;
            ListNode nextHead = tail.next;//临时存一下下剩下需要交换的链表
            tail.next = pre;
            pre.next = nextHead;
            cur.next = tail;
            cur = cur.next.next;
            pre = nextHead;          
        }
        return dummy.next;
    }
}

25. K 个一组翻转链表

public class Solution {
    //使用栈  Time:O(KN) Space:O(K)
    //惨不忍睹运行效率
    /**执行用时:
        3 ms
        , 在所有 Java 提交中击败了
        7.28%
        的用户
        内存消耗:
        41 MB
        , 在所有 Java 提交中击败了
        15.58%
        的用户
     */
    public ListNode reverseKGroup1(ListNode head, int k) {
		ListNode p = head;
    	int len = 0;
    	while(p!=null){p=p.next; len++;}
    	if(len < k) return head;
        Stack<ListNode> stack = new Stack<ListNode>();
        len = k;
        ListNode res = new ListNode(-1);
        p = head;
        ListNode cur = res;
        while(p!=null){
        	len = k;
            //入栈
        	while(p!=null && len >0){
        		len--;
        		stack.push(p);
        		p = p.next;
        	}
            //足够k个
        	while(!stack.isEmpty()&&len==0){
        		cur.next = stack.pop();
        		cur = cur.next;
        	}
            //不足k个
        	while(!stack.isEmpty()){
        		cur.next = stack.remove(0);
        		cur = cur.next;
        	}
        }
        cur.next = null; //注意最后一个要置为null
        return res.next;
    }
    /**
        执行用时:
        0 ms
        , 在所有 Java 提交中击败了
        100.00%
        的用户
        内存消耗:
        40.4 MB
        , 在所有 Java 提交中击败了
        32.27%
        的用户
     */
    public ListNode reverseKGroup(ListNode head, int k) {
        ListNode dummy = new ListNode(-1);
        dummy.next = head;
        ListNode cur = dummy;
       while(true){
            ListNode p = cur;
            for(int i = 0; i < k && p!=null; i++) p = p.next;
            if(p==null) break; //不够k个
            //翻转 cur->a->b->c->d->e->f  那么p=d  ==> 翻转k-1个cur->a<-b<-c<-d    剩下e->f
            ListNode nextHead = p.next;//记录剩下还没有翻转链表e->f
            ListNode a = cur.next, b = a.next;
            for(int i = 0; i < k - 1; i++){
                ListNode tmp = b.next; //记录还没有翻转的
                b.next = a;
                a = b;
                b = tmp;
            }
            //cur->a<-b<-c<-d  nextHead:e->f
            //剩下几步: a->nextHead;cur->d; 变成cur->d->c->b->a->nextHead;更新cur=a(需要记录一下);
            ListNode tmp = cur.next;//记录a
            cur.next.next = nextHead;//a->nextHead
            cur.next = a;//cur->d
            cur = tmp;//更新cur=a
        }
        return dummy.next;
    }
}

26. 删除有序数组中的重复项​​​​​​

class Solution {
    public int removeDuplicates(int[] nums) {
        int res = 0;
        for(int i = 0; i < nums.length; i++){
            if(i== 0 || nums[i]!= nums[i-1]){
                nums[res++] = nums[i];;
            }
        }
        return res;
    }
}

27. 移除元素

class Solution {
    public int removeElement(int[] nums, int val) {
        int res = 0;
        for(int i = 0; i < nums.length; i++) {
            if(val == nums[i]) continue;
            nums[res++] = nums[i];
        }
        return res;
    }
}

28. 实现 strStr()

class Solution {
    KMP算法 O(N)
    public int strStr(String str, String pstr) {
        if(pstr == null || pstr.length() == 0) return 0;
        int sLen = str.length(), pLen = pstr.length();
        if(sLen < pLen) return -1;//不够长罗
        char s[] = new char[sLen + 1], p[] = new char[pLen + 1];
        for(int i = 0; i< sLen; i++) s[i+1] = str.charAt(i);
        for(int i = 0; i < pLen; i++) p[i+1] = pstr.charAt(i);
        int ne[] = new int [50010];
        //计算ne数组
        for(int i = 2, j = 0; i <= pLen; i++) {
            while(j > 0 && p[i] != p[j+1]) j = ne[j];
            if(p[i] == p[j+1]) ++j;
            ne[i] = j;
        }

        for(int i = 1, j = 0; i <= sLen; i++) {
            while(j > 0 && s[i] != p[j+1]) j = ne[j];
            if(s[i] == p[j+1]) ++j;
            if(j == pLen) {
                return i - j;
            }
        }
        return -1;
    }
}

29. 两数相除

class Solution {
    /**
     * x / y = k(1100101....) =>x = y * k(1100101....)  =>x = y * 2^1 + y * 2^2+....y^k  快速幂的思想

     */
	public int divide(int dividend, int divisor) {
		if (dividend == 0) {
			return 0;
		}
		if (dividend == Integer.MIN_VALUE && divisor == -1) {
			return Integer.MAX_VALUE;
		}
		if (dividend == Integer.MIN_VALUE && divisor == 1) {
			return Integer.MIN_VALUE;
		}
		boolean isNegative = (dividend ^ divisor) < 0;
		long _dividend = Math.abs((long)dividend);
		long _divisor = Math.abs((long)divisor);
		// System.out.println(_dividend + " " + _divisor);
		int cnt = 0;
		for (int i = 31; i >= 0; --i) {
			if (_dividend >> i >= _divisor) {
				cnt += 1 << i;
				_dividend -= _divisor << i;
			}
		}
		return isNegative ? -cnt : cnt;
	}
	public int divide(int dividend, int divisor) {
        if(dividend == 0) return 0;
        boolean isNegative = false;
        if(dividend > 0 && divisor < 0 || dividend < 0 && divisor > 0) isNegative = true;
        long a = (long) dividend, b = (long)divisor;
        // long a = (long)Math.abs(dividend), b = (long) Math.abs(divisor);    int  abs有问题
        if(a < 0) a = -a;
        if(b < 0) b = -b;
        List<Long> ep = new ArrayList<>();
        for(long i = b; i <= a; i += i) {
            ep.add(i);
        }
        long res = 0;
        for(int i = ep.size() - 1; i >= 0; i--) {
            if(a >= ep.get(i)) {
                a -= ep.get(i);
                res += (long)1 << i;  //注意转换  如果是i是int  1 << i (31)时候 变为-2147483648
            }
        }
        if(isNegative) res = -res;
        if(res > 2147483647 || res < -2147483648) return 2147483647;
        return (int)res;
	}

}

​​​​​​30. 串联所有单词的子串

class Solution {
	/**
	 * 滑动窗口
	 * 在s上维护一个滑动窗口
	 * @param s
	 * @param words
	 * @return
	 */
	public List<Integer> findSubstring(String s, String[] words) {
		List<Integer> res = new ArrayList<>();
		if(s == null || words == null || s.length() == 0 || words.length ==0) 
			return res;
		
		int one_word = words[0].length();
		int word_num = words.length;
		int all_len = one_word * word_num;
		HashMap<String,Integer> map = new HashMap<>();
		for(String word : words) {
			map.put(word, map.getOrDefault(word, 0) + 1);
		}
		for(int i = 0; i < one_word; i++) {
			int left = i, right = i, count = 0;
			HashMap<String, Integer> tmp_map = new HashMap<>();
			while(right + one_word <= s.length()) {
				String w = s.substring(right, right + one_word);
				right = right + one_word;
				if(!map.containsKey(w)) {
					count = 0;
					left = right;
					tmp_map.clear();
				}else {
					tmp_map.put(w,  tmp_map.getOrDefault(w, 0) + 1);
					count++;
					while(tmp_map.get(w) > map.get(w)) {
						String t_w = s.substring(left, left + one_word);
						count--;
						tmp_map.put(t_w, tmp_map.getOrDefault(t_w, 0) - 1);
						left += one_word;
					}
					if(count == word_num) res.add(left);
				}
			}
		}
		return res;
	}
	
	/**
	 * 方法一:  通过截取s字符串和words总字符长度相同的字符串,然后对截取的
	 * 	字符串进行再次截取为单词,因为题目单词的长度相等,然后放入tmp_map中。
	 * 	words的字符串放入map中
	 *  对比map和tmp_map是否相等,相等就是s字符串的下表放入答案list中
	 *  Space:O(N)   Time:O(N^2)
	 * @param s
	 * @param words
	 * @return
	 */
	public List<Integer> findSubstring2(String s, String[] words) {
		List<Integer> res = new ArrayList<>();
		if(s == null || words == null || s.length() == 0 || words.length ==0) 
			return res;
		
		int one_word = words[0].length();
		int word_num = words.length;
		int all_len = one_word * word_num;
		HashMap<String,Integer> map = new HashMap<>();
		for(String word : words) {
			map.put(word, map.getOrDefault(word, 0) + 1);
		}
		for(int i = 0; i < s.length() - all_len + 1; i++) {
			String tmp = s.substring(i, i + all_len);
			HashMap<String,Integer> tmp_map = new HashMap<>();
			for(int j = 0; j < all_len; j+= one_word) {
				String w = tmp.substring(j, j + one_word);
				tmp_map.put(w, tmp_map.getOrDefault(w, 0) + 1);
			}
			if(map.equals(tmp_map)) res.add(i);
		}
		return res;
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
LeetCode-Editor是一种在线编码工具,它提供了一个用户友好的界面编写和运行代码。在使用LeetCode-Editor时,有时候会出现乱码的问题。 乱码的原因可能是由于编码格式不兼容或者编码错误导致的。在这种情况下,我们可以尝试以下几种解决方法: 1. 检查文件编码格式:首先,我们可以检查所编辑的文件的编码格式。通常来说,常用的编码格式有UTF-8和ASCII等。我们可以将编码格式更改为正确的格式。在LeetCode-Editor中,可以通过界面设置或编辑器设置来更改编码格式。 2. 使用正确的字符集:如果乱码是由于使用了不同的字符集导致的,我们可以尝试更改使用正确的字符集。常见的字符集如Unicode或者UTF-8等。在LeetCode-Editor中,可以在编辑器中选择正确的字符集。 3. 使用合适的编辑器:有时候,乱码问题可能与LeetCode-Editor自身相关。我们可以尝试使用其他编码工具,如Text Editor、Sublime Text或者IDE,看是否能够解决乱码问题。 4. 查找特殊字符:如果乱码问题只出现在某些特殊字符上,我们可以尝试找到并替换这些字符。通过仔细检查代码,我们可以找到导致乱码的特定字符,并进行修正或替换。 总之,解决LeetCode-Editor乱码问题的方法有很多。根据具体情况,我们可以尝试更改文件编码格式、使用正确的字符集、更换编辑器或者查找并替换特殊字符等方法来解决这个问题。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值