一連の考え
これは O(n) の複雑さを持つアルゴリズムであるため、組み込みの並べ替えアルゴリズムを使用してこの問題を解決することはできません。したがって、問題を解決するためにスペースを時間と交換してみてください。ハッシュテーブル方式を使用するだけです。
最初にすべての要素をハッシュ テーブルに格納し、次に各要素をトラバースしてハッシュ テーブル内の要素に隣接する要素があるかどうかを調べ、次に上限と下限を見つけ、2 つの差をとって 1 を引きます。なぜなら、 2 回目は、最初に減算または加算してから、ハッシュ テーブルの要素を見つけます。
コード
class Solution {
public int longestConsecutive(int[] nums) {
if(nums == null || nums.length == 0) return 0;
HashSet<Integer> set = new HashSet<>();
int res = 0;
for(int num:nums){
set.add(num);
}
for(int i = 0;i<nums.length;i++){
int down = nums[i]-1;
while(set.contains(down)){
set.remove(down);
down--;
}
int up = nums[i] + 1;
while(set.contains(up)){
set.remove(up);
up++;
}
res = Math.max(res,up-down-1);
}
return res;
}
}
一連の考え
2回と1回しか現れない数字なので、hashSetを使って解きます。
ビット単位の演算を使用して解決することもできます。XOR を使用して直接計算するだけです。
コード
ハッシュセット:
class Solution {
public int singleNumber(int[] nums) {
if(nums.length == 1) return nums[0];
HashSet<Integer> hashset = new HashSet<>();
for(int i = 0;i<nums.length;i++){
if(hashset.contains(nums[i])){
hashset.remove(nums[i]);
}else{
hashset.add(nums[i]);
}
}
return hashset.iterator().next();
}
}
ビット演算:
int res = 0;
for(int i =0;i<nums.length;i++){
res^=nums[i];
}
return res;
一連の考え
リンクされたリストにマージソートを適用するだけです。
コード
/**
* 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 ListNode sortList(ListNode head) {
if(head == null || head.next == null) return head;
ListNode midNode = mid(head);
ListNode node2 = midNode.next;
midNode.next = null;
return merge(sortList(head),sortList(node2));
}
public ListNode mid(ListNode head){
ListNode slow = head;
ListNode fast = head.next;
while(fast != null && fast.next != null){
slow = slow.next;
fast = fast.next.next;
}
return slow;
}
public ListNode merge(ListNode a,ListNode b){
ListNode dumy = new ListNode(0);
ListNode temp =dumy;
while(a != null && b != null){
if(a.val <= b.val){
temp.next = a;
a = a.next;
}else{
temp.next = b;
b = b.next;
}
temp = temp.next;
}
if(a == null)
temp.next = b;
if(b == null)
temp.next = a;
return dumy.next;
}
}
一連の考え
配列要素がトラバースされるたびに、それが負の数である場合、前の最小値を乗算すると最大になり、最大値を乗算すると最大になり、現在の要素が最大になる可能性があることに注意してください。この問題を解決するために dp 配列を使用する必要はありません。
コード
class Solution {
public int maxProduct(int[] nums) {
int max = nums[0];
int min = nums[0];
int res = nums[0];
for(int i = 1;i<nums.length;i++){
int temp = max;
max = Math.max(Math.max(max*nums[i],min*nums[i]),nums[i]);
min = Math.min(Math.min(temp*nums[i],min*nums[i]),nums[i]);
res = Math.max(res,max);
}
return res;
}
}